@fro.bot/systematic 3.5.2 → 3.5.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/ATTRIBUTIONS.md CHANGED
@@ -71,10 +71,10 @@ SOFTWARE.
71
71
 
72
72
  ## pbakaus/impeccable — Apache 2.0
73
73
 
74
- **Source repository:** [https://github.com/pbakaus/impeccable](https://github.com/pbakaus/impeccable)
75
- **Pinned commit:** `642f03d5a10eb3deb91bd511241e387e23b9aa39`
76
- **License:** Apache 2.0
77
- **Copyright:** Paul Bakaus
74
+ **Source repository:** [https://github.com/pbakaus/impeccable](https://github.com/pbakaus/impeccable)
75
+ **Pinned commit:** `642f03d5a10eb3deb91bd511241e387e23b9aa39`
76
+ **License:** Apache 2.0
77
+ **Copyright:** Paul Bakaus
78
78
 
79
79
  ### Files derived
80
80
 
@@ -272,7 +272,7 @@ The following is the full Apache License, Version 2.0 text, reproduced here in c
272
272
  ## vercel-labs/agent-browser — Apache-2.0
273
273
 
274
274
  **Source repository:** [`vercel-labs/agent-browser`](https://github.com/vercel-labs/agent-browser)
275
- **Pinned version:** `v0.33.0` (npm `agent-browser@0.33.0`)
275
+ **Pinned version:** `v0.33.1` (npm `agent-browser@0.33.1`)
276
276
  **License:** Apache-2.0
277
277
  **Copyright:** Copyright 2025 Vercel Inc.
278
278
 
@@ -289,14 +289,14 @@ Vendored verbatim from the pinned npm package (`node_modules/agent-browser/skill
289
289
  Refresh is **automated** via the pinned `devDependency` + `agent-browser:build` regeneration + `agent-browser:drift` CI gate:
290
290
 
291
291
  1. Renovate opens a version-bump PR when upstream releases a new `agent-browser` version.
292
- 2. The `postUpgradeTasks` in `renovate.json5` runs `bun run agent-browser:build`, which regenerates `skills/agent-browser/SKILL.md` from the newly pinned version and lands the updated stub in the same PR.
292
+ 2. The `postUpgradeTasks` in `renovate.json5` runs `bun run postupgrade` (which runs `bun run agent-browser:build`), which regenerates `skills/agent-browser/SKILL.md` from the newly pinned version and lands the updated stub in the same PR.
293
293
  3. The CI `agent-browser:drift` step verifies the committed file matches the pinned package and fails the PR if it does not.
294
294
 
295
295
  This is fully automated — no human adaptation pass is required, in contrast to `obra/superpowers` which is manually refreshed because its content is hand-adapted on each bump.
296
296
 
297
297
  ### Upstream Apache-2.0 license text
298
298
 
299
- The following is the full Apache License, Version 2.0 text from `agent-browser@0.33.0`, reproduced here in compliance with the license's notice requirements:
299
+ The following is the full Apache License, Version 2.0 text from `agent-browser@0.33.1`, reproduced here in compliance with the license's notice requirements:
300
300
 
301
301
  ```
302
302
  Apache License
package/dist/index.js CHANGED
@@ -1309,6 +1309,15 @@ var DEFAULT_LIMITS = {
1309
1309
  maxTotalFileBytes: 16777216,
1310
1310
  maxPathBytes: 4096
1311
1311
  };
1312
+ var UNTRACKED_FILES_ARGS = [
1313
+ "ls-files",
1314
+ "--others",
1315
+ "--exclude-standard",
1316
+ "--full-name",
1317
+ "-z",
1318
+ "--",
1319
+ ":/"
1320
+ ];
1312
1321
  function unavailable(result) {
1313
1322
  return { status: "unavailable", reasonCode: result.reasonCode };
1314
1323
  }
@@ -1420,15 +1429,15 @@ function runCommand(runner, args2, cwd, limits) {
1420
1429
  }
1421
1430
  return { status: "ok", output: { stdout: result.stdout } };
1422
1431
  }
1423
- function readRevision(runner, root, limits) {
1424
- const branch = runCommand(runner, ["symbolic-ref", "--short", "HEAD"], root, limits);
1432
+ function readRevision(runner, context, limits) {
1433
+ const branch = runCommand(runner, ["symbolic-ref", "--short", "HEAD"], context.commandDirectory, limits);
1425
1434
  if (branch.status === "error" && branch.reasonCode !== "command-failed") {
1426
1435
  return branch;
1427
1436
  }
1428
1437
  const branchValue = branch.status === "ok" ? branch.output.stdout.trim() : "detached";
1429
1438
  let head;
1430
1439
  try {
1431
- head = runner(["rev-parse", "--verify", "HEAD"], root, limits.maxCommandOutputBytes, limits.maxCommandTimeoutMs);
1440
+ head = runner(["rev-parse", "--verify", "HEAD"], context.commandDirectory, limits.maxCommandOutputBytes, limits.maxCommandTimeoutMs);
1432
1441
  } catch {
1433
1442
  return { status: "error", reasonCode: "command-failed" };
1434
1443
  }
@@ -1439,7 +1448,7 @@ function readRevision(runner, root, limits) {
1439
1448
  return { status: "error", reasonCode: "command-output-limit" };
1440
1449
  }
1441
1450
  const headValue = head.status === 0 ? head.stdout.trim() : "unborn";
1442
- const inside = runCommand(runner, ["rev-parse", "--is-inside-work-tree"], root, limits);
1451
+ const inside = runCommand(runner, ["rev-parse", "--is-inside-work-tree"], context.commandDirectory, limits);
1443
1452
  if (inside.status === "error")
1444
1453
  return inside;
1445
1454
  return {
@@ -1454,8 +1463,8 @@ function readRevision(runner, root, limits) {
1454
1463
  function isEnoent(error) {
1455
1464
  return error !== null && typeof error === "object" && "code" in error && error.code === "ENOENT";
1456
1465
  }
1457
- function appendSubmoduleFact(hash, runner, root, relativePath, limits, totalBytes) {
1458
- const submodule = runCommand(runner, ["-C", relativePath, "rev-parse", "--verify", "HEAD"], root, limits);
1466
+ function appendSubmoduleFact(hash, runner, submodulePath, relativePath, limits, totalBytes) {
1467
+ const submodule = runCommand(runner, ["rev-parse", "--verify", "HEAD"], submodulePath, limits);
1459
1468
  if (submodule.status === "error")
1460
1469
  return submodule;
1461
1470
  const revision = submodule.output.stdout.trim();
@@ -1512,9 +1521,9 @@ function appendRegularFact(hash, fileReader, absolutePath, relativePath, stat, l
1512
1521
  hash.update("\x00");
1513
1522
  return { status: "ok", totalBytes: totalBytes + content.byteLength };
1514
1523
  }
1515
- function appendFileFactV2(hash, runner, fileReader, symlinkReader, statReader, root, entry, limits, totalBytes) {
1524
+ function appendFileFactV2(hash, runner, fileReader, symlinkReader, statReader, context, entry, limits, totalBytes) {
1516
1525
  const { mode, relativePath } = entry;
1517
- const absolutePath = safePath(root, relativePath);
1526
+ const absolutePath = safePath(context.worktreeRoot, relativePath);
1518
1527
  if (!absolutePath || outputBytes(relativePath) > limits.maxPathBytes) {
1519
1528
  return { status: "error", reasonCode: "file-read-failed" };
1520
1529
  }
@@ -1525,20 +1534,20 @@ function appendFileFactV2(hash, runner, fileReader, symlinkReader, statReader, r
1525
1534
  return isEnoent(error) ? { status: "ok", totalBytes } : { status: "error", reasonCode: "file-read-failed" };
1526
1535
  }
1527
1536
  if (mode === "160000")
1528
- return appendSubmoduleFact(hash, runner, root, relativePath, limits, totalBytes);
1537
+ return appendSubmoduleFact(hash, runner, absolutePath, relativePath, limits, totalBytes);
1529
1538
  if (stat.isSymbolicLink) {
1530
1539
  return appendSymlinkFact(hash, symlinkReader, absolutePath, relativePath, limits, totalBytes);
1531
1540
  }
1532
1541
  return appendRegularFact(hash, fileReader, absolutePath, relativePath, stat, limits, totalBytes);
1533
1542
  }
1534
- function readWorktreeRevisionV2(runner, fileReader, symlinkReader, statReader, root, limits) {
1535
- const tracked = runCommand(runner, ["ls-files", "-z"], root, limits);
1543
+ function readWorktreeRevisionV2(runner, fileReader, symlinkReader, statReader, context, limits) {
1544
+ const tracked = runCommand(runner, ["ls-files", "--full-name", "-z", "--", ":/"], context.commandDirectory, limits);
1536
1545
  if (tracked.status === "error")
1537
1546
  return tracked;
1538
- const staged = runCommand(runner, ["ls-files", "--stage", "-z"], root, limits);
1547
+ const staged = runCommand(runner, ["ls-files", "--stage", "--full-name", "-z", "--", ":/"], context.commandDirectory, limits);
1539
1548
  if (staged.status === "error")
1540
1549
  return staged;
1541
- const untracked = runCommand(runner, ["ls-files", "--others", "--exclude-standard", "-z"], root, limits);
1550
+ const untracked = runCommand(runner, UNTRACKED_FILES_ARGS, context.commandDirectory, limits);
1542
1551
  if (untracked.status === "error")
1543
1552
  return untracked;
1544
1553
  const stageEntries = parseStageEntries(staged.output.stdout, limits.maxPathBytes);
@@ -1558,17 +1567,17 @@ function readWorktreeRevisionV2(runner, fileReader, symlinkReader, statReader, r
1558
1567
  hash.update("systematic:opencode-observer:worktree:v2\x00");
1559
1568
  let totalBytes = 0;
1560
1569
  for (const relativePath of paths) {
1561
- const result = appendFileFactV2(hash, runner, fileReader, symlinkReader, statReader, root, { relativePath, mode: modes.get(relativePath) ?? "" }, limits, totalBytes);
1570
+ const result = appendFileFactV2(hash, runner, fileReader, symlinkReader, statReader, context, { relativePath, mode: modes.get(relativePath) ?? "" }, limits, totalBytes);
1562
1571
  if (result.status === "error")
1563
1572
  return result;
1564
1573
  totalBytes = result.totalBytes;
1565
1574
  }
1566
1575
  return { status: "ok", digest: hash.digest("hex") };
1567
1576
  }
1568
- function readCommitClosure(runner, root, limits) {
1577
+ function readCommitClosure(runner, context, limits) {
1569
1578
  let diff;
1570
1579
  try {
1571
- diff = runner(["diff", "--quiet", "HEAD", "--", "."], root, limits.maxCommandOutputBytes, limits.maxCommandTimeoutMs);
1580
+ diff = runner(["diff", "--quiet", "HEAD", "--", ":/"], context.commandDirectory, limits.maxCommandOutputBytes, limits.maxCommandTimeoutMs);
1572
1581
  } catch {
1573
1582
  return { status: "error", reasonCode: "command-failed" };
1574
1583
  }
@@ -1581,7 +1590,7 @@ function readCommitClosure(runner, root, limits) {
1581
1590
  if (diff.status !== 0 && diff.status !== 1) {
1582
1591
  return { status: "error", reasonCode: "command-failed" };
1583
1592
  }
1584
- const untracked = runCommand(runner, ["ls-files", "--others", "--exclude-standard", "-z"], root, limits);
1593
+ const untracked = runCommand(runner, UNTRACKED_FILES_ARGS, context.commandDirectory, limits);
1585
1594
  if (untracked.status === "error")
1586
1595
  return untracked;
1587
1596
  return {
@@ -1765,8 +1774,8 @@ function readCheckReadback(runner, root, limits, pullRequest) {
1765
1774
  const state = checkState(parsedChecks.value, limits);
1766
1775
  return state === undefined ? { status: "unavailable", reasonCode: "remote-missing-field" } : remoteResultFromPullRequest(pullRequest, { checkState: state });
1767
1776
  }
1768
- function readRemoteSnapshot(runner, operation, phase, root, limits) {
1769
- return operation === "push" ? readPushRemoteSnapshot(runner, phase, root, limits) : readRemotePullRequest(runner, operation, root, limits);
1777
+ function readRemoteSnapshot(runner, operation, phase, commandDirectory, limits) {
1778
+ return operation === "push" ? readPushRemoteSnapshot(runner, phase, commandDirectory, limits) : readRemotePullRequest(runner, operation, commandDirectory, limits);
1770
1779
  }
1771
1780
  function createOpencodeOperationObserver(options) {
1772
1781
  const limits = mergeLimits(options.limits);
@@ -1801,13 +1810,17 @@ function createOpencodeOperationObserver(options) {
1801
1810
  if (root.length === 0 || outputBytes(root) > limits.maxPathBytes) {
1802
1811
  return { status: "unavailable", reasonCode: "target-unavailable" };
1803
1812
  }
1804
- const repository = readRevision(runner, root, limits);
1813
+ const context = {
1814
+ commandDirectory: targetDirectory,
1815
+ worktreeRoot: root
1816
+ };
1817
+ const repository = readRevision(runner, context, limits);
1805
1818
  if (repository.status === "error")
1806
1819
  return unavailable(repository);
1807
- const worktree = readWorktreeRevisionV2(runner, fileReader, symlinkReader, statReader, root, limits);
1820
+ const worktree = readWorktreeRevisionV2(runner, fileReader, symlinkReader, statReader, context, limits);
1808
1821
  if (worktree.status === "error")
1809
1822
  return unavailable(worktree);
1810
- const closure = readCommitClosure(runner, root, limits);
1823
+ const closure = readCommitClosure(runner, context, limits);
1811
1824
  if (closure.status === "error")
1812
1825
  return unavailable(closure);
1813
1826
  return {
@@ -1829,7 +1842,7 @@ function createOpencodeOperationObserver(options) {
1829
1842
  if (root.length === 0 || outputBytes(root) > limits.maxPathBytes) {
1830
1843
  return { status: "unavailable", reasonCode: "target-unavailable" };
1831
1844
  }
1832
- return readRemoteSnapshot(remoteRunner, operation, phase, root, limits);
1845
+ return readRemoteSnapshot(remoteRunner, operation, phase, targetDirectory, limits);
1833
1846
  }
1834
1847
  };
1835
1848
  }
@@ -8,7 +8,7 @@
8
8
  * See anomalyco/opencode commits 2793502db / 96a534d8c for the
9
9
  * server-side schema (PR #346 / v2.9.2 history).
10
10
  */
11
- export declare const OPENCODE_AGENT_COLOR_TOKENS: readonly ["primary", "secondary", "accent", "success", "warning", "error", "info"];
11
+ export declare const OPENCODE_AGENT_COLOR_TOKENS: readonly ['primary', 'secondary', 'accent', 'success', 'warning', 'error', 'info'];
12
12
  /**
13
13
  * Check whether a value is a valid agent color — either a hex literal
14
14
  * (`#RRGGBB`) or a named token from `OPENCODE_AGENT_COLOR_TOKENS`.
@@ -20,7 +20,7 @@ export declare function resolveAgent(catalog: AgentCatalogEntry[], name: string)
20
20
  */
21
21
  export declare function renderAgentCatalogCompact(catalog: AgentCatalogEntry[]): string;
22
22
  /** Pi built-in read-only tool names used as the default allowlist. */
23
- export declare const DEFAULT_READONLY_TOOLS: readonly ["read", "grep", "find", "ls"];
23
+ export declare const DEFAULT_READONLY_TOOLS: readonly ['read', 'grep', 'find', 'ls'];
24
24
  export interface ResolvedToolAllowlist {
25
25
  tools: string[];
26
26
  }
@@ -1,5 +1,5 @@
1
- export declare const BUNDLED_AGENT_NAMES: readonly ["adversarial-document-reviewer", "adversarial-reviewer", "agent-native-reviewer", "api-contract-reviewer", "architecture-strategist", "best-practices-researcher", "bug-reproduction-validator", "cli-readiness-reviewer", "code-simplicity-reviewer", "coherence-reviewer", "correctness-reviewer", "data-migrations-reviewer", "deployment-verification-agent", "design-iterator", "design-lens-reviewer", "feasibility-reviewer", "framework-docs-researcher", "git-history-analyzer", "issue-intelligence-analyst", "kieran-typescript-reviewer", "learnings-researcher", "maintainability-reviewer", "pattern-recognition-specialist", "performance-reviewer", "pr-comment-resolver", "previous-comments-reviewer", "product-lens-reviewer", "project-standards-reviewer", "reliability-reviewer", "repo-research-analyst", "scope-guardian-reviewer", "security-lens-reviewer", "security-reviewer", "slack-researcher", "spec-flow-analyzer", "systematic-implementer", "testing-reviewer"];
2
- export declare const BUNDLED_AGENT_QUALIFIED_IDS: readonly ["design/design-iterator", "document-review/adversarial-document-reviewer", "document-review/coherence-reviewer", "document-review/design-lens-reviewer", "document-review/feasibility-reviewer", "document-review/product-lens-reviewer", "document-review/scope-guardian-reviewer", "document-review/security-lens-reviewer", "research/best-practices-researcher", "research/framework-docs-researcher", "research/git-history-analyzer", "research/issue-intelligence-analyst", "research/learnings-researcher", "research/repo-research-analyst", "research/slack-researcher", "review/adversarial-reviewer", "review/agent-native-reviewer", "review/api-contract-reviewer", "review/architecture-strategist", "review/cli-readiness-reviewer", "review/code-simplicity-reviewer", "review/correctness-reviewer", "review/data-migrations-reviewer", "review/deployment-verification-agent", "review/kieran-typescript-reviewer", "review/maintainability-reviewer", "review/pattern-recognition-specialist", "review/performance-reviewer", "review/previous-comments-reviewer", "review/project-standards-reviewer", "review/reliability-reviewer", "review/security-reviewer", "review/testing-reviewer", "workflow/bug-reproduction-validator", "workflow/pr-comment-resolver", "workflow/spec-flow-analyzer", "workflow/systematic-implementer"];
3
- export declare const BUNDLED_SKILL_NAMES: readonly ["agent-browser", "agent-native-architecture", "agent-native-audit", "ce:brainstorm", "ce:compound", "ce:compound-refresh", "ce:ideate", "ce:plan", "ce:review", "ce:work", "compound-docs", "deepen-plan", "deploy-docs", "document-review", "frontend-design", "git-clean-gone-branches", "git-commit", "git-commit-push-pr", "git-worktree", "lfg", "onboarding", "orchestrating-subagents", "report-bug-ce", "reproduce-bug", "resolve-pr-feedback", "slfg", "test-browser", "test-driven-development", "todos", "using-systematic", "writing-skills"];
1
+ export declare const BUNDLED_AGENT_NAMES: readonly ['adversarial-document-reviewer', 'adversarial-reviewer', 'agent-native-reviewer', 'api-contract-reviewer', 'architecture-strategist', 'best-practices-researcher', 'bug-reproduction-validator', 'cli-readiness-reviewer', 'code-simplicity-reviewer', 'coherence-reviewer', 'correctness-reviewer', 'data-migrations-reviewer', 'deployment-verification-agent', 'design-iterator', 'design-lens-reviewer', 'feasibility-reviewer', 'framework-docs-researcher', 'git-history-analyzer', 'issue-intelligence-analyst', 'kieran-typescript-reviewer', 'learnings-researcher', 'maintainability-reviewer', 'pattern-recognition-specialist', 'performance-reviewer', 'pr-comment-resolver', 'previous-comments-reviewer', 'product-lens-reviewer', 'project-standards-reviewer', 'reliability-reviewer', 'repo-research-analyst', 'scope-guardian-reviewer', 'security-lens-reviewer', 'security-reviewer', 'slack-researcher', 'spec-flow-analyzer', 'systematic-implementer', 'testing-reviewer'];
2
+ export declare const BUNDLED_AGENT_QUALIFIED_IDS: readonly ['design/design-iterator', 'document-review/adversarial-document-reviewer', 'document-review/coherence-reviewer', 'document-review/design-lens-reviewer', 'document-review/feasibility-reviewer', 'document-review/product-lens-reviewer', 'document-review/scope-guardian-reviewer', 'document-review/security-lens-reviewer', 'research/best-practices-researcher', 'research/framework-docs-researcher', 'research/git-history-analyzer', 'research/issue-intelligence-analyst', 'research/learnings-researcher', 'research/repo-research-analyst', 'research/slack-researcher', 'review/adversarial-reviewer', 'review/agent-native-reviewer', 'review/api-contract-reviewer', 'review/architecture-strategist', 'review/cli-readiness-reviewer', 'review/code-simplicity-reviewer', 'review/correctness-reviewer', 'review/data-migrations-reviewer', 'review/deployment-verification-agent', 'review/kieran-typescript-reviewer', 'review/maintainability-reviewer', 'review/pattern-recognition-specialist', 'review/performance-reviewer', 'review/previous-comments-reviewer', 'review/project-standards-reviewer', 'review/reliability-reviewer', 'review/security-reviewer', 'review/testing-reviewer', 'workflow/bug-reproduction-validator', 'workflow/pr-comment-resolver', 'workflow/spec-flow-analyzer', 'workflow/systematic-implementer'];
3
+ export declare const BUNDLED_SKILL_NAMES: readonly ['agent-browser', 'agent-native-architecture', 'agent-native-audit', 'ce:brainstorm', 'ce:compound', 'ce:compound-refresh', 'ce:ideate', 'ce:plan', 'ce:review', 'ce:work', 'compound-docs', 'deepen-plan', 'deploy-docs', 'document-review', 'frontend-design', 'git-clean-gone-branches', 'git-commit', 'git-commit-push-pr', 'git-worktree', 'lfg', 'onboarding', 'orchestrating-subagents', 'report-bug-ce', 'reproduce-bug', 'resolve-pr-feedback', 'slfg', 'test-browser', 'test-driven-development', 'todos', 'using-systematic', 'writing-skills'];
4
4
  export type BundledAgentName = (typeof BUNDLED_AGENT_NAMES)[number];
5
5
  export type BundledSkillName = (typeof BUNDLED_SKILL_NAMES)[number];
@@ -16,9 +16,9 @@
16
16
  import { z } from 'zod';
17
17
  export declare const WorkflowGuardSchema: z.ZodDefault<z.ZodObject<{
18
18
  mode: z.ZodDefault<z.ZodEnum<{
19
+ disabled: "disabled";
19
20
  observe: "observe";
20
21
  protected: "protected";
21
- disabled: "disabled";
22
22
  }>>;
23
23
  debug: z.ZodDefault<z.ZodBoolean>;
24
24
  }, z.core.$strict>>;
@@ -28,30 +28,30 @@ export declare const AgentOverlaySchema: z.ZodObject<{
28
28
  temperature: z.ZodOptional<z.ZodNumber>;
29
29
  top_p: z.ZodOptional<z.ZodNumber>;
30
30
  mode: z.ZodOptional<z.ZodEnum<{
31
- subagent: "subagent";
32
- primary: "primary";
33
31
  all: "all";
32
+ primary: "primary";
33
+ subagent: "subagent";
34
34
  }>>;
35
35
  color: z.ZodOptional<z.ZodUnion<readonly [z.ZodEnum<{
36
+ accent: "accent";
37
+ error: "error";
38
+ info: "info";
36
39
  primary: "primary";
37
40
  secondary: "secondary";
38
- accent: "accent";
39
41
  success: "success";
40
42
  warning: "warning";
41
- error: "error";
42
- info: "info";
43
43
  }>, z.ZodString]>>;
44
44
  steps: z.ZodOptional<z.ZodNumber>;
45
45
  hidden: z.ZodOptional<z.ZodBoolean>;
46
46
  disable: z.ZodOptional<z.ZodBoolean>;
47
47
  skills: z.ZodOptional<z.ZodArray<z.ZodString>>;
48
48
  permission: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodEnum<{
49
- ask: "ask";
50
49
  allow: "allow";
50
+ ask: "ask";
51
51
  deny: "deny";
52
52
  }>, z.ZodRecord<z.ZodString, z.ZodEnum<{
53
- ask: "ask";
54
53
  allow: "allow";
54
+ ask: "ask";
55
55
  deny: "deny";
56
56
  }>>]>>>;
57
57
  }, z.core.$strict>;
@@ -61,41 +61,41 @@ export declare const CategoryOverlaySchema: z.ZodObject<{
61
61
  temperature: z.ZodOptional<z.ZodNumber>;
62
62
  top_p: z.ZodOptional<z.ZodNumber>;
63
63
  mode: z.ZodOptional<z.ZodEnum<{
64
- subagent: "subagent";
65
- primary: "primary";
66
64
  all: "all";
65
+ primary: "primary";
66
+ subagent: "subagent";
67
67
  }>>;
68
68
  color: z.ZodOptional<z.ZodUnion<readonly [z.ZodEnum<{
69
+ accent: "accent";
70
+ error: "error";
71
+ info: "info";
69
72
  primary: "primary";
70
73
  secondary: "secondary";
71
- accent: "accent";
72
74
  success: "success";
73
75
  warning: "warning";
74
- error: "error";
75
- info: "info";
76
76
  }>, z.ZodString]>>;
77
77
  steps: z.ZodOptional<z.ZodNumber>;
78
78
  hidden: z.ZodOptional<z.ZodBoolean>;
79
79
  skills: z.ZodOptional<z.ZodArray<z.ZodString>>;
80
80
  permission: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodEnum<{
81
- ask: "ask";
82
81
  allow: "allow";
82
+ ask: "ask";
83
83
  deny: "deny";
84
84
  }>, z.ZodRecord<z.ZodString, z.ZodEnum<{
85
- ask: "ask";
86
85
  allow: "allow";
86
+ ask: "ask";
87
87
  deny: "deny";
88
88
  }>>]>>>;
89
89
  }, z.core.$strict>;
90
90
  export declare const PiSubagentsAgentOverlaySchema: z.ZodObject<{
91
91
  thinking: z.ZodOptional<z.ZodEnum<{
92
- off: "off";
93
- minimal: "minimal";
92
+ high: "high";
94
93
  low: "low";
94
+ max: "max";
95
95
  medium: "medium";
96
- high: "high";
96
+ minimal: "minimal";
97
+ off: "off";
97
98
  xhigh: "xhigh";
98
- max: "max";
99
99
  }>>;
100
100
  max_turns: z.ZodOptional<z.ZodNumber>;
101
101
  tools: z.ZodOptional<z.ZodString>;
@@ -103,13 +103,13 @@ export declare const PiSubagentsAgentOverlaySchema: z.ZodObject<{
103
103
  }, z.core.$strict>;
104
104
  export declare const PiSubagentsCategoryOverlaySchema: z.ZodObject<{
105
105
  thinking: z.ZodOptional<z.ZodEnum<{
106
- off: "off";
107
- minimal: "minimal";
106
+ high: "high";
108
107
  low: "low";
108
+ max: "max";
109
109
  medium: "medium";
110
- high: "high";
110
+ minimal: "minimal";
111
+ off: "off";
111
112
  xhigh: "xhigh";
112
- max: "max";
113
113
  }>>;
114
114
  max_turns: z.ZodOptional<z.ZodNumber>;
115
115
  tools: z.ZodOptional<z.ZodString>;
@@ -118,13 +118,13 @@ export declare const PiSubagentsCategoryOverlaySchema: z.ZodObject<{
118
118
  export declare const PiSubagentsSchema: z.ZodDefault<z.ZodObject<{
119
119
  categories: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
120
120
  thinking: z.ZodOptional<z.ZodEnum<{
121
- off: "off";
122
- minimal: "minimal";
121
+ high: "high";
123
122
  low: "low";
123
+ max: "max";
124
124
  medium: "medium";
125
- high: "high";
125
+ minimal: "minimal";
126
+ off: "off";
126
127
  xhigh: "xhigh";
127
- max: "max";
128
128
  }>>;
129
129
  max_turns: z.ZodOptional<z.ZodNumber>;
130
130
  tools: z.ZodOptional<z.ZodString>;
@@ -132,13 +132,13 @@ export declare const PiSubagentsSchema: z.ZodDefault<z.ZodObject<{
132
132
  }, z.core.$strict>>>;
133
133
  agents: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
134
134
  thinking: z.ZodOptional<z.ZodEnum<{
135
- off: "off";
136
- minimal: "minimal";
135
+ high: "high";
137
136
  low: "low";
137
+ max: "max";
138
138
  medium: "medium";
139
- high: "high";
139
+ minimal: "minimal";
140
+ off: "off";
140
141
  xhigh: "xhigh";
141
- max: "max";
142
142
  }>>;
143
143
  max_turns: z.ZodOptional<z.ZodNumber>;
144
144
  tools: z.ZodOptional<z.ZodString>;
@@ -64,10 +64,10 @@ export interface LoadConfigOptions {
64
64
  export declare function loadConfig(projectDir: string, options?: LoadConfigOptions): SystematicConfig;
65
65
  export declare function loadConfigWithSources(projectDir: string, options?: LoadConfigOptions): SourceAwareConfigResult;
66
66
  export declare function getConfigPaths(projectDir: string): {
67
- customConfig?: string | undefined;
68
- customDir?: string | undefined;
69
67
  userConfig: string;
70
68
  projectConfig: string;
71
69
  userDir: string;
72
70
  projectDir: string;
71
+ customConfig?: string | undefined;
72
+ customDir?: string | undefined;
73
73
  };
@@ -5,7 +5,7 @@ import { type AgentCatalogEntry } from './agent-resolver.js';
5
5
  /** Fixed, non-configurable delegation bounds (LOCKED). */
6
6
  export declare const MAX_DELEGATE_TURNS = 20;
7
7
  export declare const DELEGATE_TOOL_NAME = "systematic_delegate";
8
- export declare const DELEGATE_EXECUTION_MODE: "sequential";
8
+ export declare const DELEGATE_EXECUTION_MODE: 'sequential';
9
9
  export type DelegateOutcome = 'completed' | 'turn_limit' | 'aborted' | 'failed';
10
10
  /** The parent session's model, narrowed to always-defined (validated before use). */
11
11
  export type DelegateParentModel = NonNullable<ExtensionContext['model']>;
@@ -1,4 +1,4 @@
1
- export declare const CANONICAL_QUESTION_WORDING: "Confirm the requested guarded transition.";
1
+ export declare const CANONICAL_QUESTION_WORDING: 'Confirm the requested guarded transition.';
2
2
  export type QuestionPurpose = 'transition' | 'session-disablement';
3
3
  export type QuestionAnswerClassification = 'affirmative' | 'non-affirmative';
4
4
  export type QuestionAttestationReasonCode = 'already-bound' | 'already-consumed' | 'already-disabled' | 'call-session-mismatch' | 'challenge-expired' | 'challenge-consumed' | 'invalid-input' | 'no-attestation' | 'non-affirmative' | 'rejected' | 'replay' | 'scope-mismatch' | 'substitution' | 'unknown-challenge' | 'unknown-request';
@@ -28,7 +28,7 @@ export interface SkillInfo {
28
28
  argumentHint?: string;
29
29
  allowedTools?: string;
30
30
  }
31
- export declare const SKILL_FRONTMATTER_FIELDS: readonly ["name", "description", "argument-hint", "disable-model-invocation", "allowed-tools", "license", "compatibility", "metadata", "user-invocable", "agent", "model", "context", "subtask"];
31
+ export declare const SKILL_FRONTMATTER_FIELDS: readonly ['name', 'description', 'argument-hint', 'disable-model-invocation', 'allowed-tools', 'license', 'compatibility', 'metadata', 'user-invocable', 'agent', 'model', 'context', 'subtask'];
32
32
  /**
33
33
  * Parse skill frontmatter from already-read file content. Split out from
34
34
  * `extractFrontmatter` so callers that also need the body (e.g. discovered-skill
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fro.bot/systematic",
3
- "version": "3.5.2",
3
+ "version": "3.5.4",
4
4
  "description": "Compound-engineering loops for OpenCode, Pi, and Claude Code",
5
5
  "type": "module",
6
6
  "homepage": "https://fro.bot/systematic",
@@ -55,6 +55,7 @@
55
55
  "registry:drift": "bun scripts/generate-registry.ts --check",
56
56
  "registry:validate": "bun scripts/build-registry.ts --validate-only",
57
57
  "claude-code:build": "bun scripts/build-claude-code-plugin.ts",
58
+ "postupgrade": "bun run build && bun run agent-browser:build",
58
59
  "prepublishOnly": "bun run build && bun run schema:generate"
59
60
  },
60
61
  "keywords": [
@@ -92,14 +93,14 @@
92
93
  "devDependencies": {
93
94
  "@biomejs/biome": "2.5.6",
94
95
  "@earendil-works/pi-coding-agent": "0.80.10",
95
- "@opencode-ai/plugin": "1.18.8",
96
- "@opencode-ai/sdk": "1.18.8",
96
+ "@opencode-ai/plugin": "1.18.9",
97
+ "@opencode-ai/sdk": "1.18.9",
97
98
  "@semantic-release/exec": "7.1.0",
98
99
  "@tintinweb/pi-subagents": "0.14.3",
99
100
  "@types/bun": "latest",
100
101
  "@types/js-yaml": "4.0.9",
101
- "@types/node": "24.13.3",
102
- "agent-browser": "0.33.0",
102
+ "@types/node": "26.1.2",
103
+ "agent-browser": "0.33.1",
103
104
  "ajv": "8.20.0",
104
105
  "ajv-formats": "3.0.1",
105
106
  "conventional-changelog-conventionalcommits": "9.3.1",
@@ -108,7 +109,7 @@
108
109
  "semantic-release": "25.0.8",
109
110
  "semantic-release-export-data": "1.2.0",
110
111
  "typebox": "1.3.8",
111
- "typescript": "6.0.3"
112
+ "typescript": "7.0.2"
112
113
  },
113
114
  "dependencies": {
114
115
  "js-yaml": "^4.1.1",
@@ -113,3 +113,5 @@ The four capabilities are subagent delegation, blocking user interaction, task t
113
113
  The bootstrap inlines the active harness profile naming the exact mechanisms for this session—consult it.
114
114
 
115
115
  When a mechanism is unavailable, present numbered options in chat and wait for questions, maintain a visible list for task tracking, and dispatch delegation sequentially or do the work inline.
116
+
117
+ Check the workflow guard availability once per execution unit. If the guard reports `unavailable` or `guard-unavailable`, treat it as terminal for that unit: do not retry `systematic_workflow_start` or `systematic_workflow_complete`. Use the documented unguarded fallback only when authorized, and report the unavailable state once.