惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

D
DataBreaches.Net
GbyAI
GbyAI
aimingoo的专栏
aimingoo的专栏
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
月光博客
月光博客
大猫的无限游戏
大猫的无限游戏
M
MIT News - Artificial intelligence
腾讯CDC
博客园 - Franky
Engineering at Meta
Engineering at Meta
C
Check Point Blog
T
The Blog of Author Tim Ferriss
有赞技术团队
有赞技术团队
Microsoft Azure Blog
Microsoft Azure Blog
MyScale Blog
MyScale Blog
I
InfoQ
Blog — PlanetScale
Blog — PlanetScale
P
Proofpoint News Feed
The GitHub Blog
The GitHub Blog
N
Netflix TechBlog - Medium
Last Week in AI
Last Week in AI
S
SegmentFault 最新的问题
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
WordPress大学
WordPress大学

Recent Commits to openclaw:main

test: merge chat side-result checks · openclaw/openclaw@ddd2c2a test: merge cron history checks · openclaw/openclaw@f7eb746 test: merge responsive navigation shell checks · openclaw/openclaw@c2e4b47 docs(changelog): add codex oauth fixes · openclaw/openclaw@628e6cd test: merge navigation routing cases · openclaw/openclaw@5d8cecb Tests: mock channel registry bundled fallback · openclaw/openclaw@2b08233 Secrets: avoid broad web search discovery for single plugin config · openclaw/openclaw@a464f59 test: merge config view browser checks · openclaw/openclaw@20cf511 fix(status): align oauth health with runtime · openclaw/openclaw@eed7116 feat: add macOS screen snapshots for monitor preview (#67954) thanks … · openclaw/openclaw@f377db1 fix: report shared auth scopes in hello-ok (#67810) thanks @BunsDev · openclaw/openclaw@0b6c39b Auto-reply: avoid eager bundled route fallback · openclaw/openclaw@3ea1bf4 Tests: narrow session binding contract setup · openclaw/openclaw@54e4e16 fix(macOS): enable undo/redo in webchat composer text input (#34962) · openclaw/openclaw@00951dc Tests: speed up channel setup promotion · openclaw/openclaw@82b529a Docs: refresh agent instructions · openclaw/openclaw@5775fe2 fix(auth): serialize OAuth refresh across agents to fix #26322 (#67876) · openclaw/openclaw@8e79080 test: allow ollama public surface boundary test · openclaw/openclaw@7d4f1a6 Docs: add test performance guardrails · openclaw/openclaw@89706d3 Tests: restore context-engine usage proof · openclaw/openclaw@e4c4f95 Tests: slim context engine runtime coverage · openclaw/openclaw@74c198f ci: retry failed custom checkouts · openclaw/openclaw@0ee5baf test: trim duplicate provider auth onboarding cases · openclaw/openclaw@1ffc02e matrix: fix sessions_spawn --thread subagent session spawning (#67643) · openclaw/openclaw@1ce2596 test: reduce auth choice fixture churn · openclaw/openclaw@857b9cd test: mock health status config boundaries · openclaw/openclaw@9d5ab4a test: mock onboard config io boundary · openclaw/openclaw@299694d test: mock legacy state plugin boundaries · openclaw/openclaw@2713089 test: mock channel install boundaries · openclaw/openclaw@b945248 test: mock doctor preview channel boundaries · openclaw/openclaw@b1a3ad4
refactor(oc-path): drop YAGNI grammar features · openclaw...
giodl73-repo · 2026-05-09 · via Recent Commits to openclaw:main

@@ -273,19 +273,13 @@ export function isValidOcPath(input: unknown): input is string {

273273

}

274274275275

/**

276-

* Positional tokens resolve to one concrete index/key based on

277-

* container size at lookup time. Unlike `*`/`**`, they pick exactly

278-

* one element so they don't trigger the wildcard guard.

279-

*

280-

* `$first` — index 0 / first-declared key

281-

* `$last` — last index / last-declared key

282-

* `-N` — Nth from end (indexable only); `-1` = last

276+

* Positional token: `$last` resolves to the last index / last-declared

277+

* key. Picks exactly one element, so it doesn't trigger wildcard guards.

283278

*/

284-

export const POS_FIRST = "$first";

285279

export const POS_LAST = "$last";

286280287281

export function isPositionalSeg(seg: string): boolean {

288-

return seg === POS_FIRST || seg === POS_LAST || /^-\d+$/.test(seg);

282+

return seg === POS_LAST;

289283

}

290284291285

/**

@@ -309,28 +303,11 @@ export interface PositionalContainer {

309303

readonly keys?: readonly string[];

310304

}

311305312-

/** Resolve `$first`/`$last`/`-N` against a container; null when out of range. */

306+

// Resolve `$last` against a container; null when empty.

313307

export function resolvePositionalSeg(seg: string, container: PositionalContainer): string | null {

314-

if (seg === POS_FIRST) {

315-

if (container.size === 0) return null;

316-

if (!container.indexable) return container.keys?.[0] ?? null;

317-

return "0";

318-

}

319-

if (seg === POS_LAST) {

320-

if (container.size === 0) return null;

321-

if (!container.indexable) return container.keys?.[container.keys.length - 1] ?? null;

322-

return String(container.size - 1);

323-

}

324-

if (/^-\d+$/.test(seg)) {

325-

if (!container.indexable) return null;

326-

// Guard against absurd magnitudes — `-9999999999` would coerce

327-

// through Number into a big negative that wraps to a positive index.

328-

const raw = Number(seg);

329-

if (!Number.isInteger(raw) || Math.abs(raw) > 1e9) return null;

330-

const n = container.size + raw;

331-

return n >= 0 && n < container.size ? String(n) : null;

332-

}

333-

return null;

308+

if (seg !== POS_LAST || container.size === 0) return null;

309+

if (!container.indexable) return container.keys?.[container.keys.length - 1] ?? null;

310+

return String(container.size - 1);

334311

}

335312336313

/**

@@ -378,13 +355,12 @@ export function parseUnionSeg(seg: string): readonly string[] | null {

378355

}

379356380357

/**

381-

* Value predicate `[key<op>value]` filters by sibling-field comparison.

382-

* Operators: `=` `!=` `*=` `^=` `$=` (string), `<` `<=` `>` `>=` (numeric).

383-

* Multi-char operators are tried before single-char so `<=` beats `<`.

358+

* Value predicate `[key<op>value]`. Operators: `=` `!=` (string),

359+

* `<` `<=` `>` `>=` (numeric). Multi-char tried before single-char.

384360

*/

385-

export type PredicateOp = "=" | "!=" | "*=" | "^=" | "$=" | "<" | "<=" | ">" | ">=";

361+

export type PredicateOp = "=" | "!=" | "<" | "<=" | ">" | ">=";

386362387-

const PREDICATE_OPS: readonly PredicateOp[] = ["!=", "*=", "^=", "$=", "<=", ">=", "<", ">", "="];

363+

const PREDICATE_OPS: readonly PredicateOp[] = ["!=", "<=", ">=", "<", ">", "="];

388364389365

export function isPredicateSeg(seg: string): boolean {

390366

if (seg.length < 4 || !seg.startsWith("[") || !seg.endsWith("]")) return false;

@@ -413,47 +389,27 @@ export function parsePredicateSeg(seg: string): PredicateSpec | null {

413389

return null;

414390

}

415391416-

/**

417-

* Evaluate a predicate against a string-coerced leaf value. Numeric

418-

* operators require both sides to coerce to finite numbers via

419-

* `Number()`. Returns false for null (non-leaf children).

420-

*/

392+

// Numeric ops require both sides to coerce to finite numbers.

421393

export function evaluatePredicate(actual: string | null, pred: PredicateSpec): boolean {

422394

if (actual === null) return false;

423395

switch (pred.op) {

424396

case "=":

425397

return actual === pred.value;

426398

case "!=":

427399

return actual !== pred.value;

428-

case "*=":

429-

return actual.includes(pred.value);

430-

case "^=":

431-

return actual.startsWith(pred.value);

432-

case "$=":

433-

return actual.endsWith(pred.value);

434400

case "<":

435401

case "<=":

436402

case ">":

437403

case ">=": {

438404

const a = Number(actual);

439405

const b = Number(pred.value);

440-

if (!Number.isFinite(a) || !Number.isFinite(b)) {

441-

return false;

442-

}

443-

switch (pred.op) {

444-

case "<":

445-

return a < b;

446-

case "<=":

447-

return a <= b;

448-

case ">":

449-

return a > b;

450-

case ">=":

451-

return a >= b;

452-

}

453-

return false;

406+

if (!Number.isFinite(a) || !Number.isFinite(b)) return false;

407+

if (pred.op === "<") return a < b;

408+

if (pred.op === "<=") return a <= b;

409+

if (pred.op === ">") return a > b;

410+

return a >= b;

454411

}

455412

}

456-

return false;

457413

}

458414459415

/**

@@ -519,12 +475,9 @@ function extractSession(queryPart: string): string | undefined {

519475

return undefined;

520476

}

521477522-

/**

523-

* Walk `s` respecting `[...]`/`{...}`/`"..."` regions. Calls `onChar`

524-

* for every character with `atTop` indicating depth-0 status.

525-

* `onChar` returns `"stop"` to short-circuit. On unbalanced

526-

* brackets/braces/quotes, calls `onUnbalanced` (which must throw).

527-

*/

478+

// Walk `s` respecting `[...]`/`{...}`/`"..."` regions. Quoted regions

479+

// are byte-literal. `onChar` returns "stop" to short-circuit;

480+

// `onUnbalanced` (must throw) fires on bracket/brace/quote imbalance.

528481

type ScanCallback = (c: string, i: number, atTop: boolean) => "stop" | void;

529482

function scanBracketAware(s: string, onChar: ScanCallback, onUnbalanced: () => never): void {

530483

let depthBracket = 0;

@@ -533,13 +486,6 @@ function scanBracketAware(s: string, onChar: ScanCallback, onUnbalanced: () => n

533486

for (let i = 0; i < s.length; i++) {

534487

const c = s[i];

535488

if (inQuote) {

536-

// `\\` / `\"` consume the next char.

537-

if (c === "\\" && i + 1 < s.length) {

538-

if (onChar(c, i, false) === "stop") return;

539-

if (onChar(s[i + 1], i + 1, false) === "stop") return;

540-

i++;

541-

continue;

542-

}

543489

if (c === '"') inQuote = false;

544490

if (onChar(c, i, false) === "stop") return;

545491

continue;

@@ -610,33 +556,22 @@ export function isQuotedSeg(seg: string): boolean {

610556

return seg.length >= 2 && seg.startsWith('"') && seg.endsWith('"');

611557

}

612558613-

/** Strip surrounding quotes and unescape `\\`/`\"`. No-op on bare segments. */

559+

/** Strip surrounding quotes. Content is byte-literal. */

614560

export function unquoteSeg(seg: string): string {

615-

if (!isQuotedSeg(seg)) return seg;

616-

const inner = seg.slice(1, -1);

617-

let out = "";

618-

for (let i = 0; i < inner.length; i++) {

619-

const c = inner[i];

620-

if (c === "\\" && i + 1 < inner.length) {

621-

const next = inner[i + 1];

622-

if (next === "\\" || next === '"') {

623-

out += next;

624-

i++;

625-

continue;

626-

}

627-

}

628-

out += c;

629-

}

630-

return out;

561+

return isQuotedSeg(seg) ? seg.slice(1, -1) : seg;

631562

}

632563633-

/** Quote a literal for path inclusion if it contains any grammar character. */

564+

// Refuses values with `"` or `\` — no escape mechanism.

634565

export function quoteSeg(value: string): string {

635566

if (value.length === 0) return '""';

636-

const needsQuote = /[/.[\]{}?&%"\s]/.test(value);

637-

if (!needsQuote) return value;

638-

const escaped = value.replace(/\\/g, "\\\\").replace(/"/g, '\\"');

639-

return `"${escaped}"`;

567+

if (value.includes('"') || value.includes("\\")) {

568+

fail(

569+

`Cannot quote value containing '"' or '\\\\': ${printable(value)}`,

570+

value,

571+

"OC_PATH_UNQUOTABLE",

572+

);

573+

}

574+

return /[/.[\]{}?&%\s]/.test(value) ? `"${value}"` : value;

640575

}

641576642577

// Defense-in-depth — the splitter validates segments it splits; this

@@ -670,8 +605,18 @@ function validateSubSegment(sub: string, input: string): void {

670605

"OC_PATH_CONTROL_CHAR",

671606

);

672607

}

673-

// Quoting opts out of identifier-shape rules — content is verbatim.

674-

if (isQuotedSeg(sub)) return;

608+

// Quoted content is byte-literal but can't contain `"` or `\`.

609+

if (isQuotedSeg(sub)) {

610+

const inner = sub.slice(1, -1);

611+

if (inner.includes('"') || inner.includes("\\")) {

612+

fail(

613+

`Quoted segment cannot contain '"' or '\\\\': ${printable(sub)}`,

614+

input,

615+

"OC_PATH_UNQUOTABLE",

616+

);

617+

}

618+

return;

619+

}

675620676621

// Reserved characters used by the path grammar itself (`?`/`&`/`%`).

677622

// Allowed inside predicate / union segments — those are content.

@@ -711,7 +656,7 @@ function validateSubSegment(sub: string, input: string): void {

711656

"OC_PATH_MALFORMED_PREDICATE",

712657

);

713658

}

714-

const hasOp = ["!=", "*=", "^=", "$=", "<=", ">=", "<", ">", "="].some((op) =>

659+

const hasOp = ["!=", "<=", ">=", "<", ">", "="].some((op) =>

715660

inner.includes(op),

716661

);

717662

if (hasOp) {