create-agdf 0.10.1 → 0.10.2

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 (87) hide show
  1. package/README.md +21 -13
  2. package/bin/agdf-validator.js +11 -0
  3. package/generated/.agdf/control/README.md +3 -3
  4. package/generated/.github/skills/agdf-brownfield-analysis/SKILL.md +1 -1
  5. package/generated/.github/skills/agdf-delivery-path-search/SKILL.md +7 -6
  6. package/generated/.github/skills/agdf-gate-check/SKILL.md +28 -91
  7. package/generated/.github/skills/agdf-interaction-locales.json +2 -0
  8. package/generated/.github/skills/contracts/gate-transition.md +4 -2
  9. package/generated/.github/skills/contracts/modes.md +12 -1
  10. package/generated/.opencode/agdf-interaction-locales.json +2 -0
  11. package/generated/.opencode/contracts/gate-transition.md +4 -2
  12. package/generated/.opencode/contracts/modes.md +12 -1
  13. package/generated/.opencode/skills/agdf-brownfield-analysis/SKILL.md +1 -1
  14. package/generated/.opencode/skills/agdf-delivery-path-search/SKILL.md +7 -6
  15. package/generated/.opencode/skills/agdf-gate-check/SKILL.md +28 -91
  16. package/generated/plugins/agdf/.claude-plugin/plugin.json +19 -0
  17. package/generated/plugins/agdf/.codex-plugin/plugin.json +1 -1
  18. package/generated/plugins/agdf/control/README.md +3 -3
  19. package/generated/plugins/agdf/hooks/session-start.sh +1 -1
  20. package/generated/plugins/agdf/meta/agdf-interaction-locales.json +2 -0
  21. package/generated/plugins/agdf/meta/agdf-plugin.definition.json +1 -1
  22. package/generated/plugins/agdf/meta/contracts/gate-transition.md +4 -2
  23. package/generated/plugins/agdf/meta/contracts/modes.md +12 -1
  24. package/generated/plugins/agdf/runtime/agdf-local.js +11 -0
  25. package/generated/plugins/agdf/runtime/create-agdf/NOTICE +10 -0
  26. package/generated/plugins/agdf/runtime/create-agdf/bin/agdf-validator.js +11 -0
  27. package/generated/plugins/agdf/runtime/create-agdf/generated/plugins/agdf/meta/agdf-interaction-locales.json +418 -0
  28. package/generated/plugins/agdf/runtime/create-agdf/generated/plugins/agdf/meta/agdf-plugin.definition.json +220 -0
  29. package/generated/plugins/agdf/runtime/create-agdf/lib/cli/command-registry.js +136 -0
  30. package/generated/plugins/agdf/runtime/create-agdf/lib/cli/delivery-path-search-command.js +75 -0
  31. package/generated/plugins/agdf/runtime/create-agdf/lib/cli/parse-args.js +156 -0
  32. package/generated/plugins/agdf/runtime/create-agdf/lib/cli/runtime-context.js +83 -0
  33. package/generated/plugins/agdf/runtime/create-agdf/lib/cli/validation-handlers.js +45 -0
  34. package/generated/plugins/agdf/runtime/create-agdf/lib/control-evaluation/delivery-map.js +291 -0
  35. package/generated/plugins/agdf/runtime/create-agdf/lib/control-evaluation/doctor.js +265 -0
  36. package/generated/plugins/agdf/runtime/create-agdf/lib/control-evaluation/gate-check.js +459 -0
  37. package/generated/plugins/agdf/runtime/create-agdf/lib/control-evaluation/gate-policy.js +283 -0
  38. package/generated/plugins/agdf/runtime/create-agdf/lib/control-evaluation/required-files.js +9 -0
  39. package/generated/plugins/agdf/runtime/create-agdf/lib/control-evaluation/run-state.js +217 -0
  40. package/generated/plugins/agdf/runtime/create-agdf/lib/control-evaluation/shared.js +344 -0
  41. package/generated/plugins/agdf/runtime/create-agdf/lib/control-evaluation/verified-change.js +156 -0
  42. package/generated/plugins/agdf/runtime/create-agdf/lib/control-state/aggregate.js +18 -0
  43. package/generated/plugins/agdf/runtime/create-agdf/lib/control-state/gate-approval-validator.js +49 -0
  44. package/generated/plugins/agdf/runtime/create-agdf/lib/control-state/index.js +7 -0
  45. package/generated/plugins/agdf/runtime/create-agdf/lib/control-state/legacy-migration.js +95 -0
  46. package/generated/plugins/agdf/runtime/create-agdf/lib/control-state/run-state-parser.js +227 -0
  47. package/generated/plugins/agdf/runtime/create-agdf/lib/control-state/run-state-repository.js +68 -0
  48. package/generated/plugins/agdf/runtime/create-agdf/lib/control-state/run-state-resolver.js +45 -0
  49. package/generated/plugins/agdf/runtime/create-agdf/lib/control-state/run-state-writer.js +97 -0
  50. package/generated/plugins/agdf/runtime/create-agdf/lib/delivery-path-search/candidate-policy.js +99 -0
  51. package/generated/plugins/agdf/runtime/create-agdf/lib/delivery-path-search/contracts.js +237 -0
  52. package/generated/plugins/agdf/runtime/create-agdf/lib/delivery-path-search/evaluators/claude.js +44 -0
  53. package/generated/plugins/agdf/runtime/create-agdf/lib/delivery-path-search/evaluators/codex.js +53 -0
  54. package/generated/plugins/agdf/runtime/create-agdf/lib/delivery-path-search/evaluators/protocol.js +13 -0
  55. package/generated/plugins/agdf/runtime/create-agdf/lib/delivery-path-search/generators/claude.js +40 -0
  56. package/generated/plugins/agdf/runtime/create-agdf/lib/delivery-path-search/generators/codex.js +38 -0
  57. package/generated/plugins/agdf/runtime/create-agdf/lib/delivery-path-search/generators/protocol.js +12 -0
  58. package/generated/plugins/agdf/runtime/create-agdf/lib/delivery-path-search/persistence.js +39 -0
  59. package/generated/plugins/agdf/runtime/create-agdf/lib/delivery-path-search/scoring.js +21 -0
  60. package/generated/plugins/agdf/runtime/create-agdf/lib/delivery-path-search/search-engine.js +154 -0
  61. package/generated/plugins/agdf/runtime/create-agdf/lib/delivery-path-search/state-adapter.js +161 -0
  62. package/generated/plugins/agdf/runtime/create-agdf/lib/delivery-path-search/surfaces/capabilities.js +14 -0
  63. package/generated/plugins/agdf/runtime/create-agdf/lib/delivery-path-search/transports/read-only-guard.js +43 -0
  64. package/generated/plugins/agdf/runtime/create-agdf/lib/interaction-presentation.js +590 -0
  65. package/generated/plugins/agdf/runtime/create-agdf/lib/runtime/local-validator.js +142 -0
  66. package/generated/plugins/agdf/runtime/create-agdf/lib/runtime/validator-application.js +40 -0
  67. package/generated/plugins/agdf/runtime/create-agdf/package.json +66 -0
  68. package/generated/plugins/agdf/runtime/runtime-manifest.json +8 -0
  69. package/generated/plugins/agdf/scripts/check-runtime-integrity.mjs +1040 -0
  70. package/generated/plugins/agdf/skills/brownfield-analysis/SKILL.md +1 -1
  71. package/generated/plugins/agdf/skills/delivery-path-search/SKILL.md +7 -6
  72. package/generated/plugins/agdf/skills/gate-check/SKILL.md +28 -91
  73. package/lib/cli/application.js +16 -54
  74. package/lib/cli/command-registry.js +9 -11
  75. package/lib/cli/validation-handlers.js +45 -0
  76. package/lib/control-evaluation/doctor.js +1 -1
  77. package/lib/control-evaluation/gate-check.js +7 -7
  78. package/lib/control-evaluation/required-files.js +9 -0
  79. package/lib/installers/local-marketplace.js +322 -0
  80. package/lib/installers/opencode.js +32 -2
  81. package/lib/installers/plugin-installers.js +102 -26
  82. package/lib/runtime/local-validator.js +142 -0
  83. package/lib/runtime/validator-application.js +40 -0
  84. package/lib/scaffold/plan.js +1 -7
  85. package/lib/scaffold/presentation.js +2 -2
  86. package/opencode-plugin.js +1 -1
  87. package/package.json +6 -2
@@ -0,0 +1,142 @@
1
+ import { createHash } from "node:crypto";
2
+ import { spawnSync } from "node:child_process";
3
+ import { existsSync, readFileSync, readdirSync, statSync } from "node:fs";
4
+ import { isAbsolute, join, relative, resolve, sep } from "node:path";
5
+ import process from "node:process";
6
+
7
+ function readJson(path) {
8
+ try {
9
+ return JSON.parse(readFileSync(path, "utf8"));
10
+ } catch {
11
+ return null;
12
+ }
13
+ }
14
+
15
+ export function digestDirectory(root) {
16
+ const files = [];
17
+ function visit(directory) {
18
+ for (const name of readdirSync(directory).sort()) {
19
+ const path = join(directory, name);
20
+ const stats = statSync(path);
21
+ if (stats.isDirectory()) visit(path);
22
+ else if (stats.isFile()) files.push(path);
23
+ }
24
+ }
25
+ visit(root);
26
+ const hash = createHash("sha256");
27
+ for (const path of files) {
28
+ hash.update(relative(root, path).replaceAll("\\", "/"));
29
+ hash.update("\0");
30
+ hash.update(readFileSync(path));
31
+ hash.update("\0");
32
+ }
33
+ return hash.digest("hex");
34
+ }
35
+
36
+ function envelope(machineValidation, options, evidence = {}) {
37
+ return {
38
+ schema_version: "1",
39
+ machine_validation: machineValidation,
40
+ surface: options.surface,
41
+ expected_version: options.expectedVersion,
42
+ observed_version: evidence.observedVersion ?? null,
43
+ source: evidence.source ?? null,
44
+ registry_access: false,
45
+ ...(evidence.reason ? { reason: evidence.reason } : {}),
46
+ };
47
+ }
48
+
49
+ export function resolveLocalValidator(options) {
50
+ if (options.ownedPackageRoot) {
51
+ const packageManifest = readJson(join(options.ownedPackageRoot, "package.json"));
52
+ const observedVersion = packageManifest?.version ?? null;
53
+ if (!packageManifest) {
54
+ return { envelope: envelope("unavailable", options, { source: "config_local_package", reason: "package_missing" }) };
55
+ }
56
+ if (observedVersion !== options.expectedVersion) {
57
+ return { envelope: envelope("version_mismatch", options, { observedVersion, source: "config_local_package" }) };
58
+ }
59
+ const entrypoint = join(options.ownedPackageRoot, "bin", "create-agdf.js");
60
+ if (!existsSync(entrypoint)) {
61
+ return { envelope: envelope("unavailable", options, { observedVersion, source: "config_local_package", reason: "entrypoint_missing" }) };
62
+ }
63
+ return {
64
+ envelope: envelope("owned_version_matched", options, { observedVersion, source: "config_local_package" }),
65
+ executable: process.execPath,
66
+ prefixArgs: [entrypoint],
67
+ };
68
+ }
69
+ const manifestPath = join(options.runtimeRoot, "runtime-manifest.json");
70
+ const manifestExists = existsSync(manifestPath);
71
+ const manifest = manifestExists ? readJson(manifestPath) : null;
72
+ if (manifestExists && !manifest) {
73
+ return { envelope: envelope("version_mismatch", options, { source: "plugin_bundle", reason: "manifest_invalid" }) };
74
+ }
75
+ if (manifest) {
76
+ const packageRoot = join(options.runtimeRoot, "create-agdf");
77
+ if (!existsSync(packageRoot)) {
78
+ return { envelope: envelope("unavailable", options, { source: "plugin_bundle", reason: "package_missing" }) };
79
+ }
80
+ const packageManifest = readJson(join(packageRoot, "package.json"));
81
+ const observedVersion = packageManifest?.version ?? manifest.version ?? null;
82
+ if (observedVersion !== options.expectedVersion || manifest.version !== options.expectedVersion) {
83
+ return { envelope: envelope("version_mismatch", options, { observedVersion, source: "plugin_bundle" }) };
84
+ }
85
+ let observedDigest = null;
86
+ try { observedDigest = digestDirectory(packageRoot); } catch {}
87
+ if (!observedDigest || manifest.digest !== observedDigest) {
88
+ return { envelope: envelope("version_mismatch", options, { observedVersion, source: "plugin_bundle", reason: "digest_mismatch" }) };
89
+ }
90
+ const entrypoint = resolve(options.runtimeRoot, manifest.entrypoint ?? "");
91
+ const entrypointRelative = relative(options.runtimeRoot, entrypoint);
92
+ if (!manifest.entrypoint || entrypointRelative === ".." || entrypointRelative.startsWith(`..${sep}`) || isAbsolute(entrypointRelative)) {
93
+ return { envelope: envelope("version_mismatch", options, { observedVersion, source: "plugin_bundle", reason: "invalid_entrypoint" }) };
94
+ }
95
+ if (!existsSync(entrypoint)) {
96
+ return { envelope: envelope("unavailable", options, { observedVersion, source: "plugin_bundle", reason: "entrypoint_missing" }) };
97
+ }
98
+ return {
99
+ envelope: envelope("owned_version_matched", options, { observedVersion, source: "plugin_bundle" }),
100
+ executable: process.execPath,
101
+ prefixArgs: [entrypoint],
102
+ };
103
+ }
104
+
105
+ const configuredPath = options.configuredPath ?? process.env.AGDF_VALIDATOR_PATH ?? "";
106
+ if (configuredPath) {
107
+ if (!isAbsolute(configuredPath) || !existsSync(configuredPath)) {
108
+ return { envelope: envelope("unavailable", options, { source: "configured_path", reason: "invalid_absolute_path" }) };
109
+ }
110
+ const versionProbe = spawnSync(configuredPath, ["--version", "--json"], { encoding: "utf8", stdio: ["ignore", "pipe", "pipe"] });
111
+ let observedVersion = null;
112
+ try { observedVersion = JSON.parse(versionProbe.stdout)?.version ?? null; } catch {}
113
+ if (versionProbe.status !== 0 || observedVersion !== options.expectedVersion) {
114
+ return { envelope: envelope("version_mismatch", options, { observedVersion, source: "configured_path" }) };
115
+ }
116
+ return {
117
+ envelope: envelope("configured_version_matched", options, { observedVersion, source: "configured_path" }),
118
+ executable: configuredPath,
119
+ prefixArgs: [],
120
+ };
121
+ }
122
+
123
+ return { envelope: envelope(options.externalRequired ? "external_required" : "unavailable", options) };
124
+ }
125
+
126
+ export function runLocalValidator(options, args, io = console) {
127
+ const resolved = resolveLocalValidator(options);
128
+ if (args[0] === "--resolve-only") {
129
+ io.log(JSON.stringify(resolved.envelope, null, args.includes("--json") ? 2 : 0));
130
+ return resolved.executable ? 0 : 2;
131
+ }
132
+ if (!resolved.executable) {
133
+ io.error(JSON.stringify(resolved.envelope));
134
+ return 2;
135
+ }
136
+ const child = spawnSync(resolved.executable, [...resolved.prefixArgs, ...args], {
137
+ cwd: options.cwd ?? process.cwd(),
138
+ env: { ...process.env, AGDF_MACHINE_VALIDATION: resolved.envelope.machine_validation },
139
+ stdio: "inherit",
140
+ });
141
+ return child.status ?? 2;
142
+ }
@@ -0,0 +1,40 @@
1
+ import process from "node:process";
2
+ import { createValidationHandlers } from "../cli/validation-handlers.js";
3
+ import { validateCommandOptions } from "../cli/command-registry.js";
4
+ import { CliUsageError, parseArgs } from "../cli/parse-args.js";
5
+ import { pluginDefinition } from "../cli/runtime-context.js";
6
+
7
+ const validatorCommands = new Set(["doctor", "gate-check", "delivery-map", "delivery-path-search"]);
8
+
9
+ export async function runValidatorCli(argv = process.argv.slice(2), adapters = {}) {
10
+ const io = adapters.io ?? console;
11
+ if (argv.includes("--version")) {
12
+ const output = { name: "create-agdf", version: pluginDefinition.version };
13
+ io.log(argv.includes("--json") ? JSON.stringify(output) : output.version);
14
+ return 0;
15
+ }
16
+ let parsed;
17
+ try {
18
+ parsed = parseArgs(argv, adapters.parser);
19
+ } catch (error) {
20
+ if (!(error instanceof CliUsageError)) throw error;
21
+ io.error(error.message);
22
+ return error.exitCode;
23
+ }
24
+ if (parsed.kind === "help") {
25
+ io.log("AGDF surface-local validator: doctor | gate-check | delivery-map | delivery-path-search");
26
+ return 0;
27
+ }
28
+ let options;
29
+ try {
30
+ options = validateCommandOptions(parsed.options);
31
+ } catch (error) {
32
+ io.error(error instanceof Error ? error.message : String(error));
33
+ return 1;
34
+ }
35
+ if (!validatorCommands.has(options.target)) {
36
+ io.error(`The surface-local validator does not support lifecycle command: ${options.target}`);
37
+ return 1;
38
+ }
39
+ return await createValidationHandlers(io).get(options.target)(options);
40
+ }
@@ -1,6 +1,7 @@
1
1
  import { existsSync, readFileSync } from "node:fs";
2
2
  import { join } from "node:path";
3
3
  import { generatedRoot, languageConfigContent, pluginDefinition } from "../cli/runtime-context.js";
4
+ export { doctorRequiredFiles } from "../control-evaluation/required-files.js";
4
5
 
5
6
  export const agdfFragmentPath = "AGENTS.agdf.md";
6
7
  const codexSkillNames = pluginDefinition.skillSet.map((skill) => `${pluginDefinition.codex.skillPrefix}${skill.slug}`);
@@ -92,13 +93,6 @@ const artefactTemplateFiles = [
92
93
  join(".agdf", "control", "templates", "artefacts", "QA_REPORT.md"),
93
94
  join(".agdf", "control", "templates", "artefacts", "OR.md"),
94
95
  ];
95
- export const doctorRequiredFiles = [
96
- join(".agdf", "control", "AGDF_RUN.md"),
97
- join(".agdf", "control", "MASTER_BACKLOG.md"),
98
- join(".agdf", "control", "SOT_REGISTRY.md"),
99
- join(".agdf", "control", "CONTEXT_GRAPH.md"),
100
- join(".agdf", "control", "AGENT_QUALITY_CONTRACTS.json"),
101
- ];
102
96
  const copilotInstructionFiles = [
103
97
  join(".github", "copilot-instructions.md"),
104
98
  join(".github", "instructions", "agdf-governance.instructions.md"),
@@ -70,13 +70,13 @@ export function printNextSteps(target, destination, files, wroteAgentsFragment,
70
70
  }
71
71
  if (target === "init") {
72
72
  io.log("- Create or migrate a canonical run, then fill its RUN_STATE.md with the current gate, evidence and next allowed action.");
73
- io.log("- Run npx --yes @agdf/cli@latest doctor to check the control state before the next agent run.");
73
+ io.log("- Run the installed `agdf doctor` to check the control state before the next agent run.");
74
74
  io.log("- Commit the live control files once they represent the repository's current delivery state.");
75
75
  return;
76
76
  }
77
77
  if (target === "config") {
78
78
  io.log("- Restart or start a new agent session so the AGDF SessionStart hook reads the updated project language config.");
79
- io.log("- Run npx --yes @agdf/cli@latest doctor when this repository also uses durable AGDF control state.");
79
+ io.log("- Run the installed `agdf doctor` when this repository also uses durable AGDF control state.");
80
80
  return;
81
81
  }
82
82
  if (wroteAgentsFragment) {
@@ -21,7 +21,7 @@ export const AGDFPlugin = async ({ directory, client }) => {
21
21
  "## AGDF Runtime Reminder",
22
22
  "This repository is AGDF-active through `.agdf/control/config.json`; use the globally installed AGDF runtime surface.",
23
23
  "For new build/change intent or unclear approval, load the native `agdf-global-gate-check` skill before later artefacts or implementation.",
24
- "Use `npx --yes @agdf/cli@latest gate-check --status-card` for compact interactive status. Use `--json` only as deterministic proof for automation or audit evidence, and summarize it instead of mirroring full JSON into chat.",
24
+ "Use the config-local `agdf/bin/agdf-local.js gate-check --status-card` for compact interactive status. Use `--json` only as deterministic proof for automation or audit evidence, and summarize it instead of mirroring full JSON into chat.",
25
25
  ].join("\n");
26
26
 
27
27
  const inactiveGuidance = [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-agdf",
3
- "version": "0.10.1",
3
+ "version": "0.10.2",
4
4
  "description": "Bootstrap AGDF repository-local plugin files, Copilot/OpenCode instructions, skills, control files and machine-readable checks.",
5
5
  "type": "module",
6
6
  "files": [
@@ -25,6 +25,10 @@
25
25
  "test:delivery-path-search-unit": "node ./scripts/delivery-path-search-unit-test.js",
26
26
  "test:delivery-path-search-generator": "node ./scripts/delivery-path-search-generator-test.js",
27
27
  "test:cli-modularization": "node ./scripts/cli-modularization-test.js",
28
+ "test:local-validator": "node ./scripts/local-validator-test.js",
29
+ "test:local-marketplace": "node ./scripts/local-marketplace-test.js",
30
+ "test:package-contents": "node ./scripts/package-contents-test.js",
31
+ "test:package-build": "node ./scripts/package-build-test.js",
28
32
  "test:lifecycle": "node ./scripts/lifecycle-test.js",
29
33
  "test:control-state": "node ./scripts/control-state-test.js",
30
34
  "test:interaction-presentation": "node ./scripts/interaction-presentation-test.js",
@@ -36,7 +40,7 @@
36
40
  "eval:skills:record": "node ./scripts/record-skill-evals.js",
37
41
  "test:release-bootstrap": "node ./scripts/release-bootstrap-smoke-test.js",
38
42
  "test:routing": "npm run sync-package-assets && node ./scripts/test-routing.js",
39
- "smoke-test": "npm run sync-package-assets && npm run test:cli-modularization && npm run test:lifecycle && npm run test:control-state && npm run test:interaction-presentation && npm run test:verified-change && npm run test:runtime-integrity-layout && npm run test:runtime-integrity-negative && npm run test:skill-evals && npm run eval:skills && npm run test:delivery-path-search && npm run test:delivery-path-search-unit && npm run test:delivery-path-search-generator && node ./scripts/smoke-test.js && node ./scripts/test-routing.js",
43
+ "smoke-test": "npm run sync-package-assets && npm run test:cli-modularization && npm run test:local-validator && npm run test:local-marketplace && npm run test:package-build && npm run test:package-contents && npm run test:lifecycle && npm run test:control-state && npm run test:interaction-presentation && npm run test:verified-change && npm run test:runtime-integrity-layout && npm run test:runtime-integrity-negative && npm run test:skill-evals && npm run eval:skills && npm run test:delivery-path-search && npm run test:delivery-path-search-unit && npm run test:delivery-path-search-generator && node ./scripts/smoke-test.js && node ./scripts/test-routing.js",
40
44
  "prepack": "npm run sync-package-assets"
41
45
  },
42
46
  "keywords": [