@zaip-ai/cli 5.1.0 → 5.3.0

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.
Files changed (80) hide show
  1. package/dist/services/adapters.d.ts +1 -1
  2. package/dist/services/adapters.js +1 -1
  3. package/dist/services/codex-literal-read-sequence-template.d.ts +2 -0
  4. package/dist/services/codex-literal-read-sequence-template.d.ts.map +1 -0
  5. package/dist/services/codex-literal-read-sequence-template.js +91 -0
  6. package/dist/services/codex-literal-read-sequence-template.js.map +1 -0
  7. package/dist/services/codex-native-tool-authority-template.d.ts.map +1 -1
  8. package/dist/services/codex-native-tool-authority-template.js +19 -12
  9. package/dist/services/codex-native-tool-authority-template.js.map +1 -1
  10. package/dist/services/codex-pre-tool-hook-template.d.ts.map +1 -1
  11. package/dist/services/codex-pre-tool-hook-template.js +11 -8
  12. package/dist/services/codex-pre-tool-hook-template.js.map +1 -1
  13. package/dist/services/codex-pre-tool-host-context-template.d.ts.map +1 -1
  14. package/dist/services/codex-pre-tool-host-context-template.js +36 -3
  15. package/dist/services/codex-pre-tool-host-context-template.js.map +1 -1
  16. package/dist/services/codex-pre-tool-support-template.d.ts.map +1 -1
  17. package/dist/services/codex-pre-tool-support-template.js +4 -43
  18. package/dist/services/codex-pre-tool-support-template.js.map +1 -1
  19. package/dist/services/codex-windows-hook-command.d.ts.map +1 -1
  20. package/dist/services/codex-windows-hook-command.js +21 -2
  21. package/dist/services/codex-windows-hook-command.js.map +1 -1
  22. package/package.json +1 -1
  23. package/templates/.agents/README-ENG.md +23 -0
  24. package/templates/.agents/README.md +24 -0
  25. package/templates/.agents/config/agents/discovery.json +1 -1
  26. package/templates/.agents/dashboard/.zaip-managed.json +30 -30
  27. package/templates/.agents/dashboard/apps/frontend/dist/assets/{DashboardHelpDialog-CngnpoLL.js → DashboardHelpDialog-URSe1IiF.js} +25 -1
  28. package/templates/.agents/dashboard/apps/frontend/dist/assets/{PricingSettingsDialog-Bszw3ekd.js → PricingSettingsDialog-8znf56to.js} +1 -1
  29. package/templates/.agents/dashboard/apps/frontend/dist/assets/{ProjectSettingsPage-IJ1znG4w.js → ProjectSettingsPage-O68yx0KF.js} +1 -1
  30. package/templates/.agents/dashboard/apps/frontend/dist/assets/{TraceabilityWorkspace-CsBpHqq_.js → TraceabilityWorkspace-DlYlyBhz.js} +1 -1
  31. package/templates/.agents/dashboard/apps/frontend/dist/assets/{dashboard-localization-D41g5rdo.js → dashboard-localization-DhvlkPf2.js} +23 -0
  32. package/templates/.agents/dashboard/apps/frontend/dist/assets/{index-Bedlm0f7.js → index-CWcci-bM.js} +2 -2
  33. package/templates/.agents/dashboard/apps/frontend/dist/index.html +1 -1
  34. package/templates/.agents/dashboard/apps/frontend/package.json +1 -1
  35. package/templates/.agents/dashboard/modules/cost-monitor/package.json +1 -1
  36. package/templates/.agents/dashboard/modules/operations/package.json +1 -1
  37. package/templates/.agents/dashboard/modules/traceability/package.json +1 -1
  38. package/templates/.agents/dashboard/packages/branding/package.json +1 -1
  39. package/templates/.agents/dashboard/packages/contracts/package.json +1 -1
  40. package/templates/.agents/dashboard/packages/data-export/package.json +1 -1
  41. package/templates/.agents/dashboard/packages/local-runtime/dist/server.cjs +162 -162
  42. package/templates/.agents/dashboard/packages/local-runtime/dist/sqlite-read-model.cjs +126 -126
  43. package/templates/.agents/dashboard/packages/local-runtime/package.json +1 -1
  44. package/templates/.agents/dashboard/packages/local-runtime/server.mjs +163 -163
  45. package/templates/.agents/dashboard/packages/local-runtime/start-dashboard.test.mjs +0 -1
  46. package/templates/.agents/dashboard/packages/ui/package.json +1 -1
  47. package/templates/.agents/dashboard/tests/e2e/package.json +1 -1
  48. package/templates/.agents/design/.zaip-managed.json +3 -3
  49. package/templates/.agents/design/apps/catalog/package.json +1 -1
  50. package/templates/.agents/design/packages/local-runtime/package.json +1 -1
  51. package/templates/.agents/requirements/autonomous-assurance.md +1 -1
  52. package/templates/.agents/requirements/cloud-hostinger-autonomy.md +1 -1
  53. package/templates/.agents/requirements/comparative-audit.md +1 -1
  54. package/templates/.agents/requirements/context-engine.md +1 -1
  55. package/templates/.agents/requirements/cost-observability.md +1 -1
  56. package/templates/.agents/requirements/dashboard-launch.md +1 -1
  57. package/templates/.agents/requirements/data-export.md +1 -1
  58. package/templates/.agents/requirements/design-system.md +1 -1
  59. package/templates/.agents/requirements/execution-engine.md +1 -1
  60. package/templates/.agents/requirements/kanban-dashboard.md +1 -1
  61. package/templates/.agents/requirements/model-orchestration.md +1 -1
  62. package/templates/.agents/requirements/public-distribution.md +1 -1
  63. package/templates/.agents/requirements/software-architecture.md +1 -1
  64. package/templates/.agents/requirements/strategic-improvements.md +1 -1
  65. package/templates/.agents/requirements/work-lifecycle.md +1 -1
  66. package/templates/.agents/requirements/zaip-strategic-95.md +1 -1
  67. package/templates/.agents/runtime/VERSION +1 -1
  68. package/templates/.agents/runtime/bin/zaip.mjs +202 -110
  69. package/templates/.agents/runtime/checksums.sha256 +5 -5
  70. package/templates/.agents/runtime/manifest.json +1 -1
  71. package/templates/.agents/runtime/provenance.json +4 -4
  72. package/templates/.agents/runtime/sbom.cdx.json +1 -1
  73. package/templates/.agents/skills/zaip-skill-execution/references/runtime-governance.md +1 -0
  74. package/templates/.agents/skills/zaip-skill-github-deploy/scripts/deploy-contract.mjs +25 -0
  75. package/templates/.agents/skills/zaip-skill-github-deploy/scripts/deploy-publication-intent.test.mjs +42 -0
  76. package/templates/.agents/skills/zaip-skill-github-deploy/scripts/github-deploy-contract.test.mjs +1 -0
  77. package/templates/.agents/skills/zaip-skill-lifecycle-closure/SKILL.md +8 -0
  78. package/templates/.agents/skills/zaip-skill-lifecycle-closure/references/post-publication-task-first.md +119 -0
  79. package/templates/.agents/zaip-aios/VERSION +1 -1
  80. package/templates/template-manifest.json +75 -67
@@ -1,6 +1,6 @@
1
1
  import { type PublicAgentCatalog } from "./agent-adapters.js";
2
2
  export { isManagedAdapter } from "./managed-adapter.js";
3
- export declare const ADAPTERS_VERSION = "5.1.0";
3
+ export declare const ADAPTERS_VERSION = "5.3.0";
4
4
  export interface AdapterFile {
5
5
  path: string;
6
6
  content: string;
@@ -11,7 +11,7 @@ export { isManagedAdapter } from "./managed-adapter.js";
11
11
  import { CODEX_GITHUB_DEPLOY_RULES, CODEX_SECURITY_RULES } from "./codex-rules.js";
12
12
  import { codexWindowsHookCommand } from "./codex-windows-hook-command.js";
13
13
  import { applyTransactionalChanges, assertSafeDestination } from "./transactional-files.js";
14
- export const ADAPTERS_VERSION = "5.1.0";
14
+ export const ADAPTERS_VERSION = "5.3.0";
15
15
  const ROOT_GUIDANCE = `# ZAIP-AIOS
16
16
 
17
17
  Read \`.agents/config/project.yaml\` first. Apply ZAIP only for literal boolean \`zaip.enabled: true\`, except framework maintenance or \`zaip enable\`. \`AGENTS.md\` is a bootstrap; canonical guidance lives in \`.agents/\`.
@@ -0,0 +1,2 @@
1
+ export declare const CODEX_LITERAL_READ_SEQUENCE: string;
2
+ //# sourceMappingURL=codex-literal-read-sequence-template.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codex-literal-read-sequence-template.d.ts","sourceRoot":"","sources":["../../src/services/codex-literal-read-sequence-template.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,2BAA2B,QAyFvC,CAAC"}
@@ -0,0 +1,91 @@
1
+ export const CODEX_LITERAL_READ_SEQUENCE = String.raw `export function createLiteralReadSequence({ shellSyntax, tokenizeLiteralCommand }) {
2
+ // Recognize only literal read-only pipelines/sequences. Quoted search text is data,
3
+ // not a PowerShell alias (for example the AC prefix in acceptance-criterion IDs).
4
+ function isLiteralGitRead(values) {
5
+ if (!/^(?:git|git\.exe)$/i.test(values[0])) return false;
6
+ // Deliberately narrow: only the fixed fsmonitor=false override, no aliases, routing, pagers, external diff,
7
+ // textconv, output files, or mutating subcommands in a read sequence.
8
+ const args = values.slice(1);
9
+ if (args.shift() !== "--no-pager" || args.shift() !== "-c" || args.shift() !== "core.fsmonitor=false") return false;
10
+ const subcommand = args.shift();
11
+ if (!["status", "log", "rev-parse", "diff"].includes(subcommand)) return false;
12
+ if (["diff", "log"].includes(subcommand) && !["--no-ext-diff", "--no-textconv"].every(flag => args.includes(flag))) return false;
13
+ if (subcommand === "log" && !["--no-patch", "--no-show-signature"].every(flag => args.includes(flag))) return false;
14
+ if (subcommand === "diff" && !["--name-only", "--name-status", "--stat", "--check"].some(flag => args.includes(flag))) return false;
15
+ const options = {
16
+ status: /^(?:-s|-b|--short|--branch|--porcelain(?:=v?[12])?|--untracked-files(?:=(?:no|normal|all))?|--ignored(?:=(?:traditional|matching|no))?)$/,
17
+ log: /^(?:--no-ext-diff|--no-textconv|--no-patch|--no-show-signature|--oneline|--all|--decorate(?:=(?:short|full|no))?|--no-decorate|--date-order|--topo-order|--reverse|--no-merges|--merges|--max-count=\d+|-\d+|--format=(?:%H|%h|%s|%H%x09%s))$/,
18
+ "rev-parse": /^(?:--show-toplevel|--git-common-dir|--absolute-git-dir|--is-inside-work-tree|--show-prefix|--verify|--short(?:=\d+)?|--symbolic-full-name|--abbrev-ref|--end-of-options)$/,
19
+ diff: /^(?:--name-only|--name-status|--stat|--check|--cached|--staged|--no-ext-diff|--no-textconv|--exit-code|--quiet)$/,
20
+ };
21
+ return args.every(value => value.startsWith("-") ? options[subcommand].test(value) :
22
+ // Plain revisions/pathspecs only; shell syntax was already parsed separately.
23
+ /^[A-Za-z0-9_./@~^:\\-]+$/.test(value));
24
+ }
25
+ function isLiteralReadSequence(command) {
26
+ const syntax = shellSyntax(command);
27
+ if (syntax.interpolation || syntax.redirection || syntax.grouping) return false;
28
+ const parts = [];
29
+ let start = 0, quote = null;
30
+ for (let index = 0; index < command.length; index++) {
31
+ const char = command[index];
32
+ if (quote !== null) {
33
+ if (char === quote) {
34
+ if (quote === "'" && command[index + 1] === "'" && process.platform === "win32") index++;
35
+ else quote = null;
36
+ }
37
+ } else if (char === "'" || char === '"') quote = char;
38
+ else if (char === ";" || char === "|") { parts.push(command.slice(start, index)); start = index + 1; }
39
+ }
40
+ if (quote !== null) return false;
41
+ parts.push(command.slice(start));
42
+ return parts.every(part => {
43
+ const values = tokenizeLiteralCommand(part);
44
+ if (!values?.length) return false;
45
+ if (isLiteralGitRead(values)) return true;
46
+ if (/^Get-Item$/i.test(values[0])) {
47
+ const args = values.slice(1);
48
+ const path = args[0] === "-LiteralPath" ? args[1] : args[0];
49
+ return args.length === (args[0] === "-LiteralPath" ? 2 : 1) &&
50
+ !!path && !/^(?:[a-z][\w-]*:)(?![\/])/i.test(path) && !/[*?]/.test(path);
51
+ }
52
+ if (/^Select-Object$/i.test(values[0])) {
53
+ const args = values.slice(1);
54
+ const metadata = /^(?:Name|FullName|Length|LastWriteTime|LastWriteTimeUtc|CreationTime|Attributes|IsReadOnly|LinkType|Target)(?:,(?:Name|FullName|Length|LastWriteTime|LastWriteTimeUtc|CreationTime|Attributes|IsReadOnly|LinkType|Target))*$/i;
55
+ const slice = args.length > 0 && args.length % 2 === 0 && args.every((value, index) =>
56
+ index % 2 === 0 ? /^(?:-First|-Last|-Skip)$/i.test(value) : /^\d+$/.test(value));
57
+ return slice ||
58
+ (args.length === 2 && args[0] === "-ExpandProperty" && args[1] === "Target") ||
59
+ (args.length === 2 && args[0] === "-Property" && metadata.test(args[1])) ||
60
+ (args.length === 1 && metadata.test(args[0]));
61
+ }
62
+ if (/^Select-String$/i.test(values[0])) {
63
+ const flags = /^(?:-SimpleMatch|-CaseSensitive|-Quiet|-List|-AllMatches|-NotMatch|-Raw)$/i;
64
+ const valued = /^(?:-Pattern|-Path|-LiteralPath|-Context|-Encoding)$/i;
65
+ for (let index = 1; index < values.length; index++) {
66
+ const value = values[index];
67
+ if (flags.test(value)) continue;
68
+ if (valued.test(value) && values[index + 1] !== undefined) { index++; continue; }
69
+ return false;
70
+ }
71
+ return values.length > 1;
72
+ }
73
+ if (/^(?:gh|gh\.exe)$/i.test(values[0])) {
74
+ if (!["run", "release"].includes(values[1]) || values[2] !== "view") return false;
75
+ const args = values.slice(3);
76
+ if (args[0] && /^[A-Za-z0-9._-]+$/.test(args[0]) && !args[0].startsWith("-")) args.shift();
77
+ for (let index = 0; index < args.length; index += 2) {
78
+ if (!["--json", "--jq"].includes(args[index]) || !args[index + 1]) return false;
79
+ }
80
+ return true;
81
+ }
82
+ if (/^(?:Get-Content|Measure-Object)$/i.test(values[0])) return true;
83
+ if (!/^(?:rg|rg\.exe)$/i.test(values[0])) return false;
84
+ return !values.slice(1).some(value => /^--(?:pre|hostname-bin)(?:=|$)/i.test(value));
85
+ });
86
+ }
87
+
88
+ return isLiteralReadSequence;
89
+ }
90
+ `;
91
+ //# sourceMappingURL=codex-literal-read-sequence-template.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codex-literal-read-sequence-template.js","sourceRoot":"","sources":["../../src/services/codex-literal-read-sequence-template.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,2BAA2B,GAAG,MAAM,CAAC,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAyFpD,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"codex-native-tool-authority-template.d.ts","sourceRoot":"","sources":["../../src/services/codex-native-tool-authority-template.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,gCAAgC,QA0QT,CAAC"}
1
+ {"version":3,"file":"codex-native-tool-authority-template.d.ts","sourceRoot":"","sources":["../../src/services/codex-native-tool-authority-template.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,gCAAgC,QAiRT,CAAC"}
@@ -1,5 +1,7 @@
1
1
  import { CODEX_VALIDATION_RUNTIME_SUPPORT } from "./codex-validation-runtime-template.js";
2
- export const CODEX_NATIVE_TOOL_AUTHORITY_HOOK = String.raw `import { execFileSync } from "node:child_process";
2
+ export const CODEX_NATIVE_TOOL_AUTHORITY_HOOK = String.raw `import { execFile } from "node:child_process";
3
+ import { promisify } from "node:util";
4
+ const executeGit = promisify(execFile);
3
5
  import { createHash } from "node:crypto";
4
6
  import { lstat, readFile, realpath } from "node:fs/promises";
5
7
  import { dirname, isAbsolute, relative, resolve } from "node:path";
@@ -223,16 +225,21 @@ export async function hasCurrentTaskOrchestratorRun(event, installedRoot, bounde
223
225
  }
224
226
 
225
227
  /** A Task's product writer is claimed centrally before any edit. */
226
- function isolatedGitMatchesClaim(repositoryRoot, authorityRoot, claim) {
227
- const git = (root, args) => execFileSync("git", ["-C", root, ...args], {
228
- encoding: "utf8", windowsHide: true, timeout: 15000,
229
- env: Object.fromEntries(Object.entries(process.env).filter(([key]) => !/^(GIT_|NODE_OPTIONS$)/i.test(key))),
230
- }).trim();
231
- if (resolve(git(repositoryRoot, ["rev-parse", "--show-toplevel"])) !== resolve(repositoryRoot) ||
232
- git(repositoryRoot, ["branch", "--show-current"]) !== claim.branch) return false;
233
- const head = git(repositoryRoot, ["rev-parse", "HEAD"]);
234
- if (head !== git(authorityRoot, ["rev-parse", claim.branch])) return false;
235
- return git(authorityRoot, ["worktree", "list", "--porcelain"]).split(/\r?\n\r?\n/).some(block => {
228
+ async function isolatedGitMatchesClaim(repositoryRoot, authorityRoot, claim) {
229
+ const deadline = performance.now() + 3500;
230
+ const git = async (root, args) => {
231
+ const remaining = Math.floor(deadline - performance.now());
232
+ if (remaining <= 0) throw new Error("writer_validation_budget_exhausted");
233
+ return (await executeGit("git", ["-C", root, ...args], {
234
+ encoding: "utf8", windowsHide: true, timeout: Math.min(1500, remaining), maxBuffer: 1048576,
235
+ env: Object.fromEntries(Object.entries(process.env).filter(([key]) => !/^(GIT_|NODE_OPTIONS$)/i.test(key))),
236
+ })).stdout.trim();
237
+ };
238
+ if (resolve(await git(repositoryRoot, ["rev-parse", "--show-toplevel"])) !== resolve(repositoryRoot) ||
239
+ await git(repositoryRoot, ["branch", "--show-current"]) !== claim.branch) return false;
240
+ const head = await git(repositoryRoot, ["rev-parse", "HEAD"]);
241
+ if (head !== await git(authorityRoot, ["rev-parse", claim.branch])) return false;
242
+ return (await git(authorityRoot, ["worktree", "list", "--porcelain"])).split(/\r?\n\r?\n/).some(block => {
236
243
  const lines = block.split(/\r?\n/);
237
244
  return lines.some(line => line.startsWith("worktree ") && resolve(line.slice(9)) === resolve(repositoryRoot)) &&
238
245
  lines.includes("HEAD " + head) && lines.includes("branch refs/heads/" + claim.branch);
@@ -261,7 +268,7 @@ export async function hasClaimedTaskWriter(event, repositoryRoot, boundedRead, d
261
268
  typeof isolated.branch === "string" && isolated.branch.startsWith("codex/") &&
262
269
  resolve(isolated.path) === resolve(repositoryRoot) &&
263
270
  resolve(isolated.canonical_workspace) === resolve(authorityRoot) &&
264
- isolatedGitMatchesClaim(repositoryRoot, authorityRoot, isolated);
271
+ await isolatedGitMatchesClaim(repositoryRoot, authorityRoot, isolated);
265
272
  } catch { return false; }
266
273
  }
267
274
  ` + CODEX_VALIDATION_RUNTIME_SUPPORT;
@@ -1 +1 @@
1
- {"version":3,"file":"codex-native-tool-authority-template.js","sourceRoot":"","sources":["../../src/services/codex-native-tool-authority-template.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gCAAgC,EAAE,MAAM,wCAAwC,CAAC;AAC1F,MAAM,CAAC,MAAM,gCAAgC,GAC3C,MAAM,CAAC,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAyQX,GAAG,gCAAgC,CAAC"}
1
+ {"version":3,"file":"codex-native-tool-authority-template.js","sourceRoot":"","sources":["../../src/services/codex-native-tool-authority-template.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gCAAgC,EAAE,MAAM,wCAAwC,CAAC;AAC1F,MAAM,CAAC,MAAM,gCAAgC,GAC3C,MAAM,CAAC,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAgRX,GAAG,gCAAgC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"codex-pre-tool-hook-template.d.ts","sourceRoot":"","sources":["../../src/services/codex-pre-tool-hook-template.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,mBAAmB,QA+mB/B,CAAC"}
1
+ {"version":3,"file":"codex-pre-tool-hook-template.d.ts","sourceRoot":"","sources":["../../src/services/codex-pre-tool-hook-template.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,mBAAmB,QAknB/B,CAAC"}
@@ -5,9 +5,9 @@ import { lstat, readFile, realpath } from "node:fs/promises";
5
5
  import { dirname, isAbsolute, relative, resolve } from "node:path";
6
6
  import { fileURLToPath } from "node:url";
7
7
  import { promisify } from "node:util";
8
- import { captureCliTurn, checkDestructivePatterns, configuredDeploymentBranches, configuredPermissionProfile, gitInvocation, inside, isLiteralReadSequence, parseHookEvent, readBoundedCanonicalText, requiresShellMutationRun, reviewedContextReadPaths, reviewedReleasePaths, rewriteCliInput, selectHookExecutionWorkspace, selectHookRepositoryRoot, shellSyntax, tokenizeLiteralCommand, validateInlineExecution } from "./zaip-pre-tool-support.mjs";
8
+ import { captureCliTurn, createHookBudget, checkDestructivePatterns, configuredDeploymentBranches, configuredPermissionProfile, gitInvocation, inside, isLiteralReadSequence, readBoundedCanonicalText, requiresShellMutationRun, reviewedContextReadPaths, reviewedReleasePaths, rewriteCliInput, selectHookExecutionWorkspace, selectHookRepositoryRoot, shellSyntax, tokenizeLiteralCommand, validateInlineExecution } from "./zaip-pre-tool-support.mjs";
9
9
  import { createCloudValidators } from "./zaip-pre-tool-cloud.mjs";
10
- const execute = promisify(execFile);
10
+ const { execute, parseEvent } = createHookBudget(promisify(execFile));
11
11
  const nativeAuthority = await import("./zaip-native-tool-authority.mjs").catch(() => null);
12
12
  const activation = await import("./zaip-hook-activation.mjs").catch(() => null);
13
13
  const installedRoot = resolve(dirname(fileURLToPath(import.meta.url)), "..", "..");
@@ -133,8 +133,8 @@ const destructivePatterns = [
133
133
  },
134
134
  ];
135
135
 
136
- function deny(reason) {
137
- activation?.recordActivation(repositoryRoot, event, "denied");
136
+ function deny(reason, record = true) {
137
+ if (record) activation?.recordActivation(repositoryRoot, event, "denied");
138
138
  writeSync(
139
139
  1,
140
140
  JSON.stringify({
@@ -195,7 +195,7 @@ async function validateExplicitFilesystemReferences(command, cwd, reviewedPaths
195
195
  if (homeReferencePattern.test(checked)) {
196
196
  deny("Direct user-profile path references are blocked; use repository-scoped paths.");
197
197
  }
198
- if (credentialReferencePattern.test(checked) || sensitiveEnvironmentPattern.test(checked)) {
198
+ if (credentialReferencePattern.test(checked.replace(/[;|&()]/g, " ")) || sensitiveEnvironmentPattern.test(checked)) {
199
199
  deny("Direct credential and secret access is blocked.");
200
200
  }
201
201
  if (/\b(?:Get-ChildItem|gci|dir|Get-Item|gi)(?:\s+-(?:LiteralPath|Path))?\s+(?:Env|Variable|Function|Alias):|\b(?:printenv|set)\s*$/i.test(checked) || /GetEnvironmentVariables\s*\(/i.test(checked)) {
@@ -214,8 +214,11 @@ async function validateExplicitFilesystemReferences(command, cwd, reviewedPaths
214
214
  if (jsonPath) { if (path.includes("\\") || !isWithinRepository(resolve(path))) deny("Explicit filesystem path escapes the repository boundary."); continue; }
215
215
  if (path.includes("\\") || !isWithinRepository(resolve(path)) || (match[2] && before && !(/\s/.test(before) || before === "=" || jsonPath)) || (after && !/\s/.test(after) && !jsonPath)) deny("Explicit operating-system paths outside the repository are blocked.");
216
216
  }
217
- if (process.platform === "win32" && /(?:^|[\s"'=(,])\\(?!\\)[^\s\\/"'<>|;]+(?:\\[^\s"'<>|;]+|\.[A-Za-z0-9]{1,10})/.test(checked)) {
218
- deny("Drive-rooted filesystem paths outside the repository are blocked.");
217
+ if (process.platform === "win32") {
218
+ for (const match of checked.matchAll(/(?:^|[\s"'=(,])(\\(?!\\)[^\s\\/"'<>|;]+(?:\\[^\s"'<>|;]+|\.[A-Za-z0-9]{1,10}))/g)) {
219
+ if (principalFullAccess) { await assertCanonicalLiteralPath(match[1], cwd); continue; }
220
+ deny("Drive-rooted filesystem paths outside the repository are blocked.");
221
+ }
219
222
  }
220
223
  for (const candidate of explicitPathCandidates(checked)) {
221
224
  if (principalFullAccess) { await assertCanonicalLiteralPath(candidate, cwd); continue; }
@@ -535,7 +538,7 @@ let raw = "";
535
538
  for await (const chunk of process.stdin) raw += chunk;
536
539
 
537
540
  let event;
538
- event = parseHookEvent(raw, deny);
541
+ event = parseEvent(raw, deny);
539
542
 
540
543
  const toolInput = event?.tool_input;
541
544
  const candidateWorkdir = typeof toolInput?.workdir === "string" && isAbsolute(toolInput.workdir) ? toolInput.workdir : event.cwd;
@@ -1 +1 @@
1
- {"version":3,"file":"codex-pre-tool-hook-template.js","sourceRoot":"","sources":["../../src/services/codex-pre-tool-hook-template.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,2BAA2B,EAAE,MAAM,oCAAoC,CAAC;AAEjF,MAAM,CAAC,MAAM,mBAAmB,GAAG,MAAM,CAAC,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA0W3C,2BAA2B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAqQ5B,CAAC"}
1
+ {"version":3,"file":"codex-pre-tool-hook-template.js","sourceRoot":"","sources":["../../src/services/codex-pre-tool-hook-template.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,2BAA2B,EAAE,MAAM,oCAAoC,CAAC;AAEjF,MAAM,CAAC,MAAM,mBAAmB,GAAG,MAAM,CAAC,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA6W3C,2BAA2B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAqQ5B,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"codex-pre-tool-host-context-template.d.ts","sourceRoot":"","sources":["../../src/services/codex-pre-tool-host-context-template.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,gCAAgC,QAyI5C,CAAC"}
1
+ {"version":3,"file":"codex-pre-tool-host-context-template.d.ts","sourceRoot":"","sources":["../../src/services/codex-pre-tool-host-context-template.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,gCAAgC,QAyK5C,CAAC"}
@@ -1,3 +1,4 @@
1
+ import { CODEX_LITERAL_READ_SEQUENCE } from "./codex-literal-read-sequence-template.js";
1
2
  export const CODEX_PRE_TOOL_HOST_CONTEXT_HOOK = String.raw `import { execFile } from "node:child_process";
2
3
  import { lstat, realpath } from "node:fs/promises";
3
4
  import { dirname, isAbsolute, resolve, toNamespacedPath } from "node:path";
@@ -5,7 +6,28 @@ import { promisify } from "node:util";
5
6
  const execute = promisify(execFile);
6
7
  const pathIdentity = value => process.platform === "win32" ? toNamespacedPath(resolve(value)).toLowerCase() : resolve(value);
7
8
 
9
+ export function createHookBudget(executeFile) {
10
+ const deadline = performance.now() + 6500;
11
+ return {
12
+ execute(file, args, options = {}) {
13
+ const remaining = Math.floor(deadline - performance.now());
14
+ if (remaining <= 0) throw new Error("Hook validation budget exhausted; inspect the slow dependency before retrying.");
15
+ return executeFile(file, args, { ...options, timeout: Math.min(options.timeout ?? remaining, remaining) });
16
+ },
17
+ parseEvent(raw, deny) {
18
+ let event; try { event = JSON.parse(raw); } catch { deny("Malformed hook input was rejected."); }
19
+ // Headroom for the Windows launcher; a stalled dependency never grants authority.
20
+ const timer = setTimeout(() => deny("Hook validation budget exhausted. Inspect the slow Git/filesystem dependency before retrying; authorization was not granted.", false), Math.max(1, deadline - performance.now()));
21
+ timer.unref();
22
+ return event;
23
+ },
24
+ };
25
+ }
26
+
8
27
  export function createHostContext({ inside, readBoundedCanonicalText }) {
28
+ // One hook invocation only: never reuse filesystem authority across tool calls.
29
+ const roots = new Map();
30
+ const deadline = performance.now() + 6000;
9
31
  /** Project configuration selects ZAIP policy; the host still enforces effective ACLs. */
10
32
  async function configuredPermissionProfile(installedRoot) {
11
33
  const restricted = { filesystem: false, network: false };
@@ -82,6 +104,11 @@ async function configuredPermissionProfile(installedRoot) {
82
104
  }
83
105
 
84
106
  async function selectHookRepositoryRoot(installedRoot, cwd) {
107
+ const key = JSON.stringify([installedRoot, cwd]);
108
+ if (!roots.has(key)) roots.set(key, resolveHookRepositoryRoot(installedRoot, cwd));
109
+ return roots.get(key);
110
+ }
111
+ async function resolveHookRepositoryRoot(installedRoot, cwd) {
85
112
  if (typeof cwd !== "string") throw new Error("Tool execution without a workspace is blocked.");
86
113
  const physicalCwd = await realpath(cwd).catch(() => null);
87
114
  if (!physicalCwd || pathIdentity(physicalCwd) !== pathIdentity(cwd)) {
@@ -95,13 +122,18 @@ async function selectHookRepositoryRoot(installedRoot, cwd) {
95
122
  if (cursor.toLowerCase() === installedRoot.toLowerCase()) return installedRoot;
96
123
  }
97
124
  try {
98
- const git = async (path, ...args) => (await execute("git", ["-C", path, ...args], {
99
- encoding: "utf8", windowsHide: true, timeout: 5000, maxBuffer: 1048576,
100
- })).stdout.trim();
125
+ const git = async (path, ...args) => {
126
+ const remaining = Math.floor(deadline - performance.now());
127
+ if (remaining <= 0) throw new Error("workspace_validation_budget_exhausted");
128
+ return (await execute("git", ["-C", path, ...args], {
129
+ encoding: "utf8", windowsHide: true, timeout: Math.min(2000, remaining), maxBuffer: 1048576,
130
+ })).stdout.trim();
131
+ };
101
132
  const primary = await git(installedRoot, "rev-parse", "--show-toplevel");
102
133
  if ((await realpath(primary)).toLowerCase() !== installedRoot.toLowerCase()) throw new Error("primary_not_root");
103
134
  const worktrees = await git(installedRoot, "worktree", "list", "--porcelain", "-z");
104
135
  const registered = worktrees.split("\0").filter(line => line.startsWith("worktree ")).map(line => line.slice(9));
136
+ if (!registered.some(path => inside(cwd, resolve(path)))) throw new Error("worktree_not_registered");
105
137
  const candidate = await realpath(await git(cwd, "rev-parse", "--show-toplevel"));
106
138
  if (!registered.some(path => resolve(path).toLowerCase() === candidate.toLowerCase()) || !inside(cwd, candidate)) {
107
139
  throw new Error("worktree_not_registered");
@@ -135,5 +167,6 @@ async function selectHookExecutionWorkspace(installedRoot, event, allowExternal
135
167
 
136
168
  return { configuredPermissionProfile, selectHookRepositoryRoot, selectHookExecutionWorkspace };
137
169
  }
170
+ ${CODEX_LITERAL_READ_SEQUENCE}
138
171
  `;
139
172
  //# sourceMappingURL=codex-pre-tool-host-context-template.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"codex-pre-tool-host-context-template.js","sourceRoot":"","sources":["../../src/services/codex-pre-tool-host-context-template.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,gCAAgC,GAAG,MAAM,CAAC,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAyIzD,CAAC"}
1
+ {"version":3,"file":"codex-pre-tool-host-context-template.js","sourceRoot":"","sources":["../../src/services/codex-pre-tool-host-context-template.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,2BAA2B,EAAE,MAAM,2CAA2C,CAAC;AAExF,MAAM,CAAC,MAAM,gCAAgC,GAAG,MAAM,CAAC,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAwKxD,2BAA2B;CAC5B,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"codex-pre-tool-support-template.d.ts","sourceRoot":"","sources":["../../src/services/codex-pre-tool-support-template.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,2BAA2B,QAqXvC,CAAC"}
1
+ {"version":3,"file":"codex-pre-tool-support-template.d.ts","sourceRoot":"","sources":["../../src/services/codex-pre-tool-support-template.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,2BAA2B,QA8UvC,CAAC"}
@@ -1,7 +1,7 @@
1
1
  export const CODEX_PRE_TOOL_SUPPORT_HOOK = String.raw `import { lstat, readFile, realpath } from "node:fs/promises";
2
2
  import { dirname, isAbsolute, relative, resolve, toNamespacedPath } from "node:path";
3
3
  import { homedir } from "node:os";
4
- import { createHostContext } from "./zaip-pre-tool-host-context.mjs";
4
+ import { createHostContext, createLiteralReadSequence } from "./zaip-pre-tool-host-context.mjs";
5
5
  import { createCliTurnCapture } from "./zaip-pre-tool-cli-capture.mjs";
6
6
  export { readAuthorityRunRecords, checkDestructivePatterns, configuredDeploymentBranches } from "./zaip-native-tool-authority.mjs";
7
7
  const pathIdentity = value => process.platform === "win32" ? toNamespacedPath(resolve(value)).toLowerCase() : resolve(value);
@@ -24,6 +24,8 @@ export function parseHookEvent(raw, deny) {
24
24
  catch { deny("Malformed hook input was rejected."); }
25
25
  }
26
26
 
27
+ export { createHookBudget } from "./zaip-pre-tool-host-context.mjs";
28
+
27
29
  export const { configuredPermissionProfile, selectHookRepositoryRoot, selectHookExecutionWorkspace } = createHostContext({ inside, readBoundedCanonicalText });
28
30
 
29
31
  export function tokenizeLiteralCommand(command) {
@@ -97,48 +99,7 @@ export function requiresShellMutationRun(command, tokens, cwd, repositoryRoot) {
97
99
  return (tokens && isSedMutation(tokens)) || shellMutationPattern.test(command) || syntax.redirection;
98
100
  }
99
101
 
100
- // Recognize only literal read-only pipelines/sequences. Quoted search text is data,
101
- // not a PowerShell alias (for example the AC prefix in acceptance-criterion IDs).
102
- export function isLiteralReadSequence(command) {
103
- const syntax = shellSyntax(command);
104
- if (syntax.interpolation || syntax.redirection || syntax.grouping) return false;
105
- const parts = [];
106
- let start = 0, quote = null;
107
- for (let index = 0; index < command.length; index++) {
108
- const char = command[index];
109
- if (quote !== null) {
110
- if (char === quote) {
111
- if (quote === "'" && command[index + 1] === "'" && process.platform === "win32") index++;
112
- else quote = null;
113
- }
114
- } else if (char === "'" || char === '"') quote = char;
115
- else if (char === ";" || char === "|") { parts.push(command.slice(start, index)); start = index + 1; }
116
- }
117
- if (quote !== null) return false;
118
- parts.push(command.slice(start));
119
- return parts.every(part => {
120
- const values = tokenizeLiteralCommand(part);
121
- if (!values?.length) return false;
122
- if (/^Get-Item$/i.test(values[0])) {
123
- const args = values.slice(1);
124
- const path = args[0] === "-LiteralPath" ? args[1] : args[0];
125
- return args.length === (args[0] === "-LiteralPath" ? 2 : 1) &&
126
- !!path && !/^(?:[a-z][\w-]*:)(?![\/])/i.test(path) && !/[*?]/.test(path);
127
- }
128
- if (/^Select-Object$/i.test(values[0])) {
129
- const args = values.slice(1);
130
- const metadata = /^(?:Name|FullName|Length|LastWriteTime|LastWriteTimeUtc|CreationTime|Attributes|IsReadOnly|LinkType|Target)(?:,(?:Name|FullName|Length|LastWriteTime|LastWriteTimeUtc|CreationTime|Attributes|IsReadOnly|LinkType|Target))*$/i;
131
- return (args.length === 2 && args[0] === "-First" && /^\d+$/.test(args[1])) ||
132
- (args.length === 2 && args[0] === "-ExpandProperty" && args[1] === "Target") ||
133
- (args.length === 2 && args[0] === "-Property" && metadata.test(args[1])) ||
134
- (args.length === 1 && metadata.test(args[0]));
135
- }
136
- if (/^(?:Get-Content|Measure-Object)$/i.test(values[0])) return true;
137
- if (!/^(?:rg|rg\.exe)$/i.test(values[0])) return false;
138
- return !values.slice(1).some(value => /^--(?:pre|hostname-bin)(?:=|$)/i.test(value));
139
- });
140
- }
141
-
102
+ export const isLiteralReadSequence = createLiteralReadSequence({ shellSyntax, tokenizeLiteralCommand });
142
103
  function isSedMutation(tokens) {
143
104
  const executable = ((tokens[0] ?? "").split(/[\\/]/).pop() ?? "").replace(/\.(?:exe|cmd|bat)$/i, "");
144
105
  return /^sed$/i.test(executable) && tokens.slice(1).some((token) =>
@@ -1 +1 @@
1
- {"version":3,"file":"codex-pre-tool-support-template.js","sourceRoot":"","sources":["../../src/services/codex-pre-tool-support-template.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,2BAA2B,GAAG,MAAM,CAAC,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAqXpD,CAAC"}
1
+ {"version":3,"file":"codex-pre-tool-support-template.js","sourceRoot":"","sources":["../../src/services/codex-pre-tool-support-template.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,2BAA2B,GAAG,MAAM,CAAC,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8UpD,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"codex-windows-hook-command.d.ts","sourceRoot":"","sources":["../../src/services/codex-windows-hook-command.ts"],"names":[],"mappings":"AAEA,wEAAwE;AACxE,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,MAAM,GAAG,MAAM,CAQpF"}
1
+ {"version":3,"file":"codex-windows-hook-command.d.ts","sourceRoot":"","sources":["../../src/services/codex-windows-hook-command.ts"],"names":[],"mappings":"AAEA,wEAAwE;AACxE,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,MAAM,GAAG,MAAM,CA2BpF"}
@@ -3,10 +3,29 @@ import { resolve } from "node:path";
3
3
  export function codexWindowsHookCommand(hook, workspaceRoot) {
4
4
  if (!/^zaip-[a-z-]+\.mjs$/.test(hook))
5
5
  throw new Error(`Invalid ZAIP hook name: ${hook}`);
6
- const literalRoot = workspaceRoot === undefined
6
+ const search = workspaceRoot === undefined
7
7
  ? "(Get-Location)"
8
8
  : `'${resolve(workspaceRoot).replaceAll("'", "''")}'`;
9
- const script = `$ProgressPreference = 'SilentlyContinue'; $search = ${literalRoot}; $git = $null; while ($search) { $candidate = Join-Path $search '.local/git/cmd/git.exe'; if (Test-Path -LiteralPath $candidate -PathType Leaf) { $git = $candidate; break }; $parent = Split-Path -Path $search -Parent; if (!$parent -or $parent -eq $search) { break }; $search = $parent }; if (!$git) { $git = (Get-Command git -ErrorAction SilentlyContinue).Source }; if (!$git) { exit 0 }; $root = & $git rev-parse --show-toplevel 2>$null; if ($LASTEXITCODE -ne 0 -or !$root) { exit 0 }; $hook = Join-Path $root '.codex/hooks/${hook}'; if (!(Test-Path -LiteralPath $hook -PathType Leaf)) { exit 0 }; & node $hook; exit $LASTEXITCODE`;
9
+ const script = [
10
+ "$ProgressPreference = 'SilentlyContinue'",
11
+ `$search = ${search}`,
12
+ "$git = $null",
13
+ "while ($search) { $candidate = Join-Path $search '.local/git/cmd/git.exe'; if (Test-Path -LiteralPath $candidate -PathType Leaf) { $git = $candidate; break }; $parent = Split-Path -Path $search -Parent; if (!$parent -or $parent -eq $search) { break }; $search = $parent }",
14
+ "if (!$git) { $git = (Get-Command git -ErrorAction SilentlyContinue).Source }",
15
+ "if (!$git) { exit 0 }",
16
+ "$probe = New-Object System.Diagnostics.Process",
17
+ "$probe.StartInfo.FileName = $git",
18
+ "$probe.StartInfo.Arguments = 'rev-parse --show-toplevel'",
19
+ "$probe.StartInfo.UseShellExecute = $false",
20
+ "$probe.StartInfo.CreateNoWindow = $true",
21
+ "$probe.StartInfo.RedirectStandardOutput = $true",
22
+ "$probe.StartInfo.RedirectStandardError = $true",
23
+ "try { if (!$probe.Start()) { throw 'git discovery failed' }; $output = $probe.StandardOutput.ReadToEndAsync(); $errors = $probe.StandardError.ReadToEndAsync(); if (!$probe.WaitForExit(1500)) { $probe.Kill(); [Console]::Error.WriteLine('ZAIP hook: Git discovery exceeded 1500ms; retry after checking Git availability.'); exit 2 }; $root = $output.GetAwaiter().GetResult().Trim(); if ($probe.ExitCode -ne 0 -or !$root) { exit 0 } } catch { [Console]::Error.WriteLine('ZAIP hook: Git discovery failed.'); exit 2 } finally { $probe.Dispose() }",
24
+ `$hook = Join-Path $root '.codex/hooks/${hook}'`,
25
+ "if (!(Test-Path -LiteralPath $hook -PathType Leaf)) { exit 0 }",
26
+ "& node $hook",
27
+ "exit $LASTEXITCODE",
28
+ ].join("; ");
10
29
  return `powershell -NoProfile -NonInteractive -EncodedCommand ${Buffer.from(script, "utf16le").toString("base64")}`;
11
30
  }
12
31
  //# sourceMappingURL=codex-windows-hook-command.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"codex-windows-hook-command.js","sourceRoot":"","sources":["../../src/services/codex-windows-hook-command.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,wEAAwE;AACxE,MAAM,UAAU,uBAAuB,CAAC,IAAY,EAAE,aAAsB;IAC1E,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,2BAA2B,IAAI,EAAE,CAAC,CAAC;IAC1F,MAAM,WAAW,GACf,aAAa,KAAK,SAAS;QACzB,CAAC,CAAC,gBAAgB;QAClB,CAAC,CAAC,IAAI,OAAO,CAAC,aAAa,CAAC,CAAC,UAAU,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC;IAC1D,MAAM,MAAM,GAAG,uDAAuD,WAAW,ihBAAihB,IAAI,qGAAqG,CAAC;IAC5sB,OAAO,yDAAyD,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;AACtH,CAAC"}
1
+ {"version":3,"file":"codex-windows-hook-command.js","sourceRoot":"","sources":["../../src/services/codex-windows-hook-command.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,wEAAwE;AACxE,MAAM,UAAU,uBAAuB,CAAC,IAAY,EAAE,aAAsB;IAC1E,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,2BAA2B,IAAI,EAAE,CAAC,CAAC;IAC1F,MAAM,MAAM,GACV,aAAa,KAAK,SAAS;QACzB,CAAC,CAAC,gBAAgB;QAClB,CAAC,CAAC,IAAI,OAAO,CAAC,aAAa,CAAC,CAAC,UAAU,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC;IAC1D,MAAM,MAAM,GAAG;QACb,0CAA0C;QAC1C,aAAa,MAAM,EAAE;QACrB,cAAc;QACd,iRAAiR;QACjR,8EAA8E;QAC9E,uBAAuB;QACvB,gDAAgD;QAChD,kCAAkC;QAClC,0DAA0D;QAC1D,2CAA2C;QAC3C,yCAAyC;QACzC,iDAAiD;QACjD,gDAAgD;QAChD,6hBAA6hB;QAC7hB,yCAAyC,IAAI,GAAG;QAChD,gEAAgE;QAChE,cAAc;QACd,oBAAoB;KACrB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACb,OAAO,yDAAyD,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;AACtH,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zaip-ai/cli",
3
- "version": "5.1.0",
3
+ "version": "5.3.0",
4
4
  "description": "CLI oficial para instalar e configurar o ZAIP-AIOS em qualquer repositório",
5
5
  "type": "module",
6
6
  "license": "SEE LICENSE IN LICENSE",
@@ -12,6 +12,29 @@ test reuse, content-based Dashboard builds and separate npm confirmation.
12
12
  Authorized maintenance suspends governance while keeping telemetry active;
13
13
  governance is restored and hooks are checked when maintenance ends.
14
14
 
15
+ The [hook repair guide](https://github.com/zaip-ai/zaip-aios/blob/main/docs/quality/hooks-leitura-e-orcamento.md) describes
16
+ permitted Git read sequences, validation time budgets, and retained protections.
17
+ Git read sequences use `git --no-pager -c core.fsmonitor=false` and the documented
18
+ safe options; Git mutations still require separate commands.
19
+
20
+ The [v5.2 reliability plan](https://github.com/zaip-ai/zaip-aios/blob/main/docs/quality/v52-confiabilidade-e-eficiencia.md)
21
+ records bounded Git discovery in the Windows launcher, observation recovery
22
+ after maintenance, thread-scoped Run queries, and validation cache measurements.
23
+ Evidence distinguishes local tests, independent review, and package publication.
24
+
25
+ The [v5.3 governance and recovery contract](https://github.com/zaip-ai/zaip-aios/blob/main/docs/quality/v53-governanca-e-retomada.md)
26
+ defines recovery for published Task-first deliveries, Run continuity,
27
+ authenticated remote resumption, and criteria for measuring actual test savings.
28
+ Legacy failure reconciliation uses complete signed reruns, preserves history,
29
+ and prevents resolved failures from imposing indefinite retests. It does not
30
+ waive impact checks or turn an unverified installation into a cache HIT.
31
+ Literal audit queries using `Select-String`, numeric `Select-Object` slices,
32
+ and `gh run view`/`gh release view` are reads; interpolation, remote writes,
33
+ redirection, and secret access retain their controls.
34
+ On Windows, rooted paths used by the principal in `zaip-aios-full-access` undergo
35
+ canonical validation; literal search patterns are not blocked merely because
36
+ they contain a backslash. Traversal and protected destinations remain denied.
37
+
15
38
  > **Source, candidate, and publication:** this README describes the checkout's
16
39
  > contracts and features. The [evolution matrix](https://github.com/zaip-ai/zaip-aios/blob/main/docs/quality/v50-documentacao-editorial.md)
17
40
  > identifies implementation and evidence. Local qualification, consumer hook
@@ -12,6 +12,30 @@ o reuso conservador de testes, o build do Dashboard por conteúdo e a confirmaç
12
12
  separada do npm. Manutenção autorizada suspende a governança com telemetria ativa;
13
13
  ao terminar, a governança é reativada e os hooks são verificados.
14
14
 
15
+ O [guia de correção dos hooks](https://github.com/zaip-ai/zaip-aios/blob/main/docs/quality/hooks-leitura-e-orcamento.md) descreve
16
+ as sequências Git de leitura permitidas, os limites de tempo da validação e as
17
+ proteções preservadas. Sequências Git de leitura usam o prefixo
18
+ `git --no-pager -c core.fsmonitor=false` e as opções seguras documentadas;
19
+ alterações Git continuam exigindo comandos separados.
20
+
21
+ O [plano de confiabilidade da v5.2](https://github.com/zaip-ai/zaip-aios/blob/main/docs/quality/v52-confiabilidade-e-eficiencia.md)
22
+ registra a descoberta Git limitada no launcher Windows, a retomada da observação
23
+ após manutenção, a consulta de Runs por chat e a medição do cache de validação.
24
+ As evidências distinguem testes locais, revisão e publicação do pacote.
25
+
26
+ O [contrato de governança e retomada da v5.3](https://github.com/zaip-ai/zaip-aios/blob/main/docs/quality/v53-governanca-e-retomada.md)
27
+ define a recuperação de entregas Task-first publicadas, a continuidade de Runs,
28
+ a retomada remota autenticada e os critérios para medir economia real de testes.
29
+ A reconciliação de falhas antigas usa reexecuções completas e assinadas, preserva
30
+ o histórico e evita que uma falha já resolvida imponha retestes indefinidamente.
31
+ Isso não dispensa os testes por impacto nem transforma uma instalação não verificada em HIT.
32
+ Consultas literais de auditoria com `Select-String`, recortes numéricos de
33
+ `Select-Object` e `gh run view`/`gh release view` são leituras; interpolação,
34
+ escrita remota, redirecionamento e acesso a segredos conservam seus controles.
35
+ No Windows, caminhos rooted do principal em `zaip-aios-full-access` passam pela
36
+ validação canônica; padrões literais de busca não causam bloqueio apenas por
37
+ conter uma barra invertida. Travessia e destinos protegidos continuam recusados.
38
+
15
39
  > **Fonte, candidato e publicação:** este README descreve os contratos e recursos
16
40
  > do checkout. A [matriz de evolução](https://github.com/zaip-ai/zaip-aios/blob/main/docs/quality/v50-documentacao-editorial.md)
17
41
  > identifica a implementação e suas provas. Qualificação local, ativação dos
@@ -1,5 +1,5 @@
1
1
  {
2
- "_zaip_managed": "zaip-managed generated-do-not-edit source=agent-discovery version=5.1.0 sha256=3def7a2b43c1a751f8e68754ef94cb107a80b5d26e11f065af2b4cc145fc8897",
2
+ "_zaip_managed": "zaip-managed generated-do-not-edit source=agent-discovery version=5.3.0 sha256=3def7a2b43c1a751f8e68754ef94cb107a80b5d26e11f065af2b4cc145fc8897",
3
3
  "schema_version": 1,
4
4
  "source": {
5
5
  "path": ".agents/config/agents/catalog.yaml",