frontend-project-context 1.2.0 → 1.3.1

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.
@@ -0,0 +1,56 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "urn:frontend-project-context:schema:stage-context-bundle:1",
4
+ "title": "Frontend Project Context Stage Context Bundle",
5
+ "type": "object",
6
+ "additionalProperties": false,
7
+ "required": ["schemaVersion", "kind", "project", "task", "stage", "workspace", "planDigest", "snapshots", "dependencyReceipts", "changedPaths", "contractItems", "readTargets", "findings", "excluded", "budget", "status", "bundleDigest"],
8
+ "properties": {
9
+ "schemaVersion": { "const": 1 },
10
+ "kind": { "const": "stage-context-bundle" },
11
+ "project": { "$ref": "#/$defs/identity" },
12
+ "task": { "$ref": "#/$defs/task" },
13
+ "stage": { "$ref": "#/$defs/stage" },
14
+ "workspace": { "$ref": "#/$defs/workspace" },
15
+ "planDigest": { "$ref": "#/$defs/digest" },
16
+ "snapshots": { "$ref": "#/$defs/snapshots" },
17
+ "dependencyReceipts": { "type": "array", "items": { "$ref": "#/$defs/receiptSummary" } },
18
+ "changedPaths": { "$ref": "#/$defs/paths" },
19
+ "contractItems": { "type": "array", "items": { "$ref": "#/$defs/contractItem" } },
20
+ "readTargets": { "type": "array", "items": { "$ref": "#/$defs/readTarget" } },
21
+ "findings": { "type": "array", "items": { "type": "object" } },
22
+ "excluded": { "type": "array", "uniqueItems": true, "items": { "type": "string" } },
23
+ "budget": {
24
+ "type": "object",
25
+ "additionalProperties": false,
26
+ "required": ["unit", "maxUtf8Bytes", "maxReadTargets", "usedUtf8Bytes", "readTargetCount"],
27
+ "properties": {
28
+ "unit": { "const": "canonical-utf8-bytes" },
29
+ "maxUtf8Bytes": { "type": "integer", "minimum": 1 },
30
+ "maxReadTargets": { "type": "integer", "minimum": 1 },
31
+ "usedUtf8Bytes": { "type": "integer", "minimum": 0 },
32
+ "readTargetCount": { "type": "integer", "minimum": 0 }
33
+ }
34
+ },
35
+ "status": { "enum": ["ready", "blocked"] },
36
+ "bundleDigest": { "$ref": "#/$defs/digest" }
37
+ },
38
+ "$defs": {
39
+ "digest": { "type": "string", "pattern": "^sha256:[a-f0-9]{64}$" },
40
+ "identity": { "type": "object", "additionalProperties": false, "required": ["id", "name"], "properties": { "id": { "$ref": "#/$defs/id" }, "name": { "$ref": "#/$defs/text" } } },
41
+ "id": { "type": "string", "pattern": "^[a-z0-9]+(?:[.-][a-z0-9]+)*$" },
42
+ "text": { "type": "string", "minLength": 1 },
43
+ "paths": { "type": "array", "uniqueItems": true, "items": { "type": "string", "minLength": 1 } },
44
+ "snapshots": { "type": "object", "additionalProperties": false, "required": ["contract", "sourcesLock", "projectionsLock"], "properties": { "contract": { "$ref": "#/$defs/digest" }, "sourcesLock": { "$ref": "#/$defs/digest" }, "projectionsLock": { "$ref": "#/$defs/digest" } } },
45
+ "task": { "type": "object", "additionalProperties": false, "required": ["id", "title", "goal"], "properties": { "id": { "$ref": "#/$defs/id" }, "title": { "$ref": "#/$defs/text" }, "goal": { "$ref": "#/$defs/text" } } },
46
+ "acceptance": { "type": "object", "additionalProperties": false, "required": ["id", "text"], "properties": { "id": { "$ref": "#/$defs/id" }, "text": { "$ref": "#/$defs/text" } } },
47
+ "stage": { "type": "object", "additionalProperties": false, "required": ["id", "title", "objective", "acceptance", "paths"], "properties": { "id": { "$ref": "#/$defs/id" }, "title": { "$ref": "#/$defs/text" }, "objective": { "$ref": "#/$defs/text" }, "acceptance": { "type": "array", "minItems": 1, "items": { "$ref": "#/$defs/acceptance" } }, "paths": { "$ref": "#/$defs/paths" } } },
48
+ "workspace": { "type": "object", "additionalProperties": false, "required": ["branchLabel", "baseRevision"], "properties": { "branchLabel": { "$ref": "#/$defs/text" }, "baseRevision": { "$ref": "#/$defs/text" } } },
49
+ "acceptanceResult": { "type": "object", "additionalProperties": false, "required": ["id", "status", "evidence"], "properties": { "id": { "$ref": "#/$defs/id" }, "status": { "enum": ["observed", "not-observed"] }, "evidence": { "$ref": "#/$defs/paths" } } },
50
+ "verificationResult": { "type": "object", "additionalProperties": false, "required": ["id", "status", "summary", "evidence"], "properties": { "id": { "$ref": "#/$defs/id" }, "status": { "enum": ["passed", "failed", "observed", "skipped"] }, "summary": { "$ref": "#/$defs/text" }, "evidence": { "$ref": "#/$defs/paths" } } },
51
+ "receiptSummary": { "type": "object", "additionalProperties": false, "required": ["stageId", "status", "inputBundleDigest", "changedPaths", "acceptanceResults", "verificationResults", "decisions", "openIssues"], "properties": { "stageId": { "$ref": "#/$defs/id" }, "status": { "enum": ["completed", "blocked"] }, "inputBundleDigest": { "$ref": "#/$defs/digest" }, "changedPaths": { "$ref": "#/$defs/paths" }, "acceptanceResults": { "type": "array", "items": { "$ref": "#/$defs/acceptanceResult" } }, "verificationResults": { "type": "array", "items": { "$ref": "#/$defs/verificationResult" } }, "decisions": { "type": "array", "uniqueItems": true, "items": { "$ref": "#/$defs/text" } }, "openIssues": { "type": "array", "uniqueItems": true, "items": { "$ref": "#/$defs/text" } } } },
52
+ "scope": { "type": "object", "additionalProperties": false, "required": ["kind"], "properties": { "kind": { "enum": ["project", "path-prefix", "file"] }, "path": { "type": "string", "minLength": 1 } } },
53
+ "contractItem": { "type": "object", "additionalProperties": false, "required": ["id", "kind", "subject", "value", "statement", "scope", "sourceIds"], "properties": { "id": { "$ref": "#/$defs/id" }, "kind": { "enum": ["fact", "policy", "reference", "validation-description"] }, "subject": { "$ref": "#/$defs/id" }, "value": {}, "statement": { "$ref": "#/$defs/text" }, "scope": { "$ref": "#/$defs/scope" }, "sourceIds": { "type": "array", "minItems": 1, "uniqueItems": true, "items": { "$ref": "#/$defs/id" } } } },
54
+ "readTarget": { "type": "object", "additionalProperties": false, "required": ["path", "reason"], "properties": { "path": { "type": "string", "minLength": 1 }, "reason": { "enum": ["stage-scope", "host-changed-path-signal", "contract-source"] }, "sourceId": { "$ref": "#/$defs/id" } } }
55
+ }
56
+ }
@@ -0,0 +1,55 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "urn:frontend-project-context:schema:stage-receipt:1",
4
+ "title": "Frontend Project Context Stage Receipt",
5
+ "type": "object",
6
+ "additionalProperties": false,
7
+ "required": ["schemaVersion", "kind", "projectId", "taskId", "stageId", "planDigest", "inputBundleDigest", "status", "changedPaths", "acceptanceResults", "verificationResults", "decisions", "openIssues"],
8
+ "properties": {
9
+ "schemaVersion": { "const": 1 },
10
+ "kind": { "const": "stage-receipt" },
11
+ "projectId": { "$ref": "#/$defs/id" },
12
+ "taskId": { "$ref": "#/$defs/id" },
13
+ "stageId": { "$ref": "#/$defs/id" },
14
+ "planDigest": { "$ref": "#/$defs/digest" },
15
+ "inputBundleDigest": { "$ref": "#/$defs/digest" },
16
+ "status": { "enum": ["completed", "blocked"] },
17
+ "changedPaths": { "$ref": "#/$defs/paths" },
18
+ "acceptanceResults": {
19
+ "type": "array",
20
+ "items": {
21
+ "type": "object",
22
+ "additionalProperties": false,
23
+ "required": ["id", "status", "evidence"],
24
+ "properties": {
25
+ "id": { "$ref": "#/$defs/id" },
26
+ "status": { "enum": ["observed", "not-observed"] },
27
+ "evidence": { "$ref": "#/$defs/paths" }
28
+ }
29
+ }
30
+ },
31
+ "verificationResults": {
32
+ "type": "array",
33
+ "items": {
34
+ "type": "object",
35
+ "additionalProperties": false,
36
+ "required": ["id", "status", "summary", "evidence"],
37
+ "properties": {
38
+ "id": { "$ref": "#/$defs/id" },
39
+ "status": { "enum": ["passed", "failed", "observed", "skipped"] },
40
+ "summary": { "type": "string", "minLength": 1 },
41
+ "evidence": { "$ref": "#/$defs/paths" }
42
+ }
43
+ }
44
+ },
45
+ "decisions": { "$ref": "#/$defs/texts" },
46
+ "openIssues": { "$ref": "#/$defs/texts" },
47
+ "nextStageId": { "$ref": "#/$defs/id" }
48
+ },
49
+ "$defs": {
50
+ "id": { "type": "string", "pattern": "^[a-z0-9]+(?:[.-][a-z0-9]+)*$" },
51
+ "digest": { "type": "string", "pattern": "^sha256:[a-f0-9]{64}$" },
52
+ "paths": { "type": "array", "uniqueItems": true, "items": { "type": "string", "minLength": 1 } },
53
+ "texts": { "type": "array", "uniqueItems": true, "items": { "type": "string", "minLength": 1 } }
54
+ }
55
+ }
@@ -0,0 +1,85 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "urn:frontend-project-context:schema:task-context-plan:1",
4
+ "title": "Frontend Project Context Task Context Plan",
5
+ "type": "object",
6
+ "additionalProperties": false,
7
+ "required": ["schemaVersion", "kind", "projectId", "task", "workspace", "snapshots", "budget", "stages"],
8
+ "properties": {
9
+ "schemaVersion": { "const": 1 },
10
+ "kind": { "const": "task-context-plan" },
11
+ "projectId": { "$ref": "#/$defs/id" },
12
+ "task": {
13
+ "type": "object",
14
+ "additionalProperties": false,
15
+ "required": ["id", "title", "goal", "acceptance"],
16
+ "properties": {
17
+ "id": { "$ref": "#/$defs/id" },
18
+ "title": { "$ref": "#/$defs/text" },
19
+ "goal": { "$ref": "#/$defs/text" },
20
+ "acceptance": {
21
+ "type": "array",
22
+ "minItems": 1,
23
+ "items": {
24
+ "type": "object",
25
+ "additionalProperties": false,
26
+ "required": ["id", "text"],
27
+ "properties": { "id": { "$ref": "#/$defs/id" }, "text": { "$ref": "#/$defs/text" } }
28
+ }
29
+ }
30
+ }
31
+ },
32
+ "workspace": {
33
+ "type": "object",
34
+ "additionalProperties": false,
35
+ "required": ["branchLabel", "baseRevision"],
36
+ "properties": { "branchLabel": { "$ref": "#/$defs/text" }, "baseRevision": { "$ref": "#/$defs/text" } }
37
+ },
38
+ "snapshots": { "$ref": "#/$defs/snapshots" },
39
+ "budget": {
40
+ "type": "object",
41
+ "additionalProperties": false,
42
+ "required": ["maxUtf8Bytes", "maxReadTargets"],
43
+ "properties": {
44
+ "maxUtf8Bytes": { "type": "integer", "minimum": 1 },
45
+ "maxReadTargets": { "type": "integer", "minimum": 1 }
46
+ }
47
+ },
48
+ "stages": {
49
+ "type": "array",
50
+ "minItems": 1,
51
+ "items": {
52
+ "type": "object",
53
+ "additionalProperties": false,
54
+ "required": ["id", "title", "objective", "dependsOn", "paths", "acceptanceIds"],
55
+ "properties": {
56
+ "id": { "$ref": "#/$defs/id" },
57
+ "title": { "$ref": "#/$defs/text" },
58
+ "objective": { "$ref": "#/$defs/text" },
59
+ "dependsOn": { "$ref": "#/$defs/ids" },
60
+ "paths": { "$ref": "#/$defs/paths" },
61
+ "acceptanceIds": { "$ref": "#/$defs/nonEmptyIds" }
62
+ }
63
+ }
64
+ }
65
+ },
66
+ "$defs": {
67
+ "id": { "type": "string", "pattern": "^[a-z0-9]+(?:[.-][a-z0-9]+)*$" },
68
+ "text": { "type": "string", "minLength": 1 },
69
+ "digest": { "type": "string", "pattern": "^sha256:[a-f0-9]{64}$" },
70
+ "path": { "type": "string", "minLength": 1 },
71
+ "ids": { "type": "array", "uniqueItems": true, "items": { "$ref": "#/$defs/id" } },
72
+ "nonEmptyIds": { "type": "array", "minItems": 1, "uniqueItems": true, "items": { "$ref": "#/$defs/id" } },
73
+ "paths": { "type": "array", "minItems": 1, "uniqueItems": true, "items": { "$ref": "#/$defs/path" } },
74
+ "snapshots": {
75
+ "type": "object",
76
+ "additionalProperties": false,
77
+ "required": ["contract", "sourcesLock", "projectionsLock"],
78
+ "properties": {
79
+ "contract": { "$ref": "#/$defs/digest" },
80
+ "sourcesLock": { "$ref": "#/$defs/digest" },
81
+ "projectionsLock": { "$ref": "#/$defs/digest" }
82
+ }
83
+ }
84
+ }
85
+ }
@@ -0,0 +1,74 @@
1
+ import { ASSIST_BUNDLE_SCHEMA_VERSION } from "./assist.mjs";
2
+ import { DASHBOARD_SCHEMA_VERSION } from "./dashboard-model.mjs";
3
+ import {
4
+ ACTION_KINDS,
5
+ ACTION_PLAN_SCHEMA_VERSION,
6
+ CAPABILITIES_SCHEMA_VERSION,
7
+ COMMANDS,
8
+ EXCHANGE_PROTOCOL_VERSION,
9
+ PACKAGE_VERSION,
10
+ REVIEW_BUNDLE_SCHEMA_VERSION,
11
+ } from "./exchange-schema.mjs";
12
+ import { inspectProjectInitialization, loadProject } from "./project-store.mjs";
13
+ import { RENDERER_VERSION } from "./renderer.mjs";
14
+ import {
15
+ CONTEXT_BUDGET_UNIT,
16
+ INTEGRATION_REVIEW_BUNDLE_SCHEMA_VERSION,
17
+ STAGE_CONTEXT_BUNDLE_SCHEMA_VERSION,
18
+ STAGE_RECEIPT_SCHEMA_VERSION,
19
+ TASK_CONTEXT_PLAN_SCHEMA_VERSION,
20
+ } from "./task-context-schema.mjs";
21
+
22
+ function schemas() {
23
+ return {
24
+ actionPlan: ACTION_PLAN_SCHEMA_VERSION,
25
+ assistBundle: ASSIST_BUNDLE_SCHEMA_VERSION,
26
+ capabilities: CAPABILITIES_SCHEMA_VERSION,
27
+ contract: 2,
28
+ dashboardViewModel: DASHBOARD_SCHEMA_VERSION,
29
+ integrationReviewBundle: INTEGRATION_REVIEW_BUNDLE_SCHEMA_VERSION,
30
+ projectionLock: 1,
31
+ projectionRenderer: RENDERER_VERSION,
32
+ proposal: 1,
33
+ reviewBundle: REVIEW_BUNDLE_SCHEMA_VERSION,
34
+ sourceLock: 1,
35
+ stageContextBundle: STAGE_CONTEXT_BUNDLE_SCHEMA_VERSION,
36
+ stageReceipt: STAGE_RECEIPT_SCHEMA_VERSION,
37
+ taskContextPlan: TASK_CONTEXT_PLAN_SCHEMA_VERSION,
38
+ };
39
+ }
40
+
41
+ export async function buildCapabilities(root) {
42
+ const initialization = await inspectProjectInitialization(root);
43
+ let project = null;
44
+ if (initialization.status === "initialized") {
45
+ const loaded = await loadProject(root);
46
+ project = { id: loaded.contract.project.id, name: loaded.contract.project.name };
47
+ }
48
+ return {
49
+ schemaVersion: CAPABILITIES_SCHEMA_VERSION,
50
+ package: { name: "frontend-project-context", version: PACKAGE_VERSION },
51
+ exchangeProtocolVersion: EXCHANGE_PROTOCOL_VERSION,
52
+ schemas: schemas(),
53
+ commands: [...COMMANDS],
54
+ actionKinds: [...ACTION_KINDS],
55
+ contextBudget: { unit: CONTEXT_BUDGET_UNIT, modelTokens: false, callerMustProvideLimit: true },
56
+ initialization: initialization.status,
57
+ initialized: initialization.status === "initialized",
58
+ project,
59
+ boundaries: {
60
+ provider: false,
61
+ agentRuntime: false,
62
+ git: false,
63
+ network: false,
64
+ dependencyInstallation: false,
65
+ automaticApproval: false,
66
+ businessCodeWrites: false,
67
+ taskExecution: false,
68
+ stagePathBodyReads: false,
69
+ applyPlan: false,
70
+ scheduler: false,
71
+ daemon: false,
72
+ },
73
+ };
74
+ }
@@ -16,6 +16,7 @@ import { normalizeRelativePath, resolveExistingInside, resolveProjectRoot, resol
16
16
  import { initializeProject, inspectProjectInitialization, loadProject } from "./project-store.mjs";
17
17
  import { publishProjection } from "./projection-store.mjs";
18
18
  import { renderContextBundle } from "./renderer.mjs";
19
+ import { buildIntegrationReviewBundleFiles, buildStageContextBundleFiles } from "./task-context.mjs";
19
20
 
20
21
  const HELP = `project-context — model-neutral project contract compiler
21
22
 
@@ -38,6 +39,8 @@ Usage:
38
39
  project-context dashboard --project PATH [--json]
39
40
  project-context sync --project PATH [--changed-path RELATIVE_PATH...] [--json]
40
41
  project-context preflight --project PATH --plan FILE [--json]
42
+ project-context stage-context --project PATH --plan FILE --stage STAGE_ID [--receipt FILE...] [--receipt-bundle FILE...] [--changed-path RELATIVE_PATH...] [--json]
43
+ project-context integration-review --project PATH --plan FILE [--receipt FILE...] [--receipt-bundle FILE...] [--main-changed-path RELATIVE_PATH...] [--branch-changed-path RELATIVE_PATH...] [--json]
41
44
 
42
45
  All commands are read-only unless their own --write flag is present.
43
46
  `;
@@ -45,9 +48,11 @@ const VALUE_FLAGS = new Set([
45
48
  "project", "id", "name", "output", "proposal", "by", "task", "target", "rationale",
46
49
  "kind", "pointer", "reference", "subject", "value", "value-json", "statement", "scope", "scope-path",
47
50
  "verification", "verification-source", "verification-expected-json",
48
- "expected-digest", "expected-item-digest", "expected-source-digest", "locale", "plan",
51
+ "expected-digest", "expected-item-digest", "expected-source-digest", "locale", "plan", "stage",
52
+ ]);
53
+ const LIST_FLAGS = new Set([
54
+ "ids", "path", "changed-path", "sources", "overrides", "affected-items", "receipt", "receipt-bundle", "main-changed-path", "branch-changed-path",
49
55
  ]);
50
- const LIST_FLAGS = new Set(["ids", "path", "changed-path", "sources", "overrides", "affected-items"]);
51
56
  const BOOLEAN_FLAGS = new Set(["write", "json", "full-json", "help", "pending"]);
52
57
  const COMMAND_OPTIONS = new Map([
53
58
  ["init", new Set(["project", "id", "name", "write", "json", "help"])],
@@ -81,6 +86,8 @@ const COMMAND_OPTIONS = new Map([
81
86
  ["dashboard", new Set(["project", "json", "help"])],
82
87
  ["sync", new Set(["project", "changed-path", "json", "help"])],
83
88
  ["preflight", new Set(["project", "plan", "json", "help"])],
89
+ ["stage-context", new Set(["project", "plan", "stage", "receipt", "receipt-bundle", "changed-path", "json", "help"])],
90
+ ["integration-review", new Set(["project", "plan", "receipt", "receipt-bundle", "main-changed-path", "branch-changed-path", "json", "help"])],
84
91
  ]);
85
92
 
86
93
  export function parseArgs(argv) {
@@ -330,6 +337,26 @@ async function runCommand(command, options) {
330
337
  const summary = `Preflight ${bundle.status}: ${bundle.summary.reviewable} reviewable, ${bundle.summary.blocked} blocked action(s).\n`;
331
338
  return { exitCode: bundle.status === "reviewable" ? 0 : 1, stdout: jsonOrText(options, bundle, summary), stderr: "" };
332
339
  }
340
+ if (command === "stage-context") {
341
+ const bundle = await buildStageContextBundleFiles(root, required(options, "plan"), {
342
+ stageId: required(options, "stage"),
343
+ receiptPaths: options.receipt ?? [],
344
+ receiptBundlePaths: options["receipt-bundle"] ?? [],
345
+ changedPaths: options["changed-path"] ?? [],
346
+ });
347
+ const summary = `Stage context ${bundle.status}: ${bundle.stage.id}; ${bundle.contractItems.length} contract item(s), ${bundle.readTargets.length} read target(s), ${bundle.budget.usedUtf8Bytes}/${bundle.budget.maxUtf8Bytes} UTF-8 bytes.\n`;
348
+ return { exitCode: bundle.status === "ready" ? 0 : 1, stdout: jsonOrText(options, bundle, summary), stderr: "" };
349
+ }
350
+ if (command === "integration-review") {
351
+ const bundle = await buildIntegrationReviewBundleFiles(root, required(options, "plan"), {
352
+ receiptPaths: options.receipt ?? [],
353
+ receiptBundlePaths: options["receipt-bundle"] ?? [],
354
+ mainChangedPaths: options["main-changed-path"] ?? [],
355
+ branchChangedPaths: options["branch-changed-path"] ?? [],
356
+ });
357
+ const summary = `Integration review ${bundle.status}: ${bundle.findings.length} finding(s), ${bundle.contractOverlapItemIds.length} contract overlap(s), ${bundle.decisionCandidates.length} decision candidate(s).\n`;
358
+ return { exitCode: bundle.status === "reviewable" ? 0 : 1, stdout: jsonOrText(options, bundle, summary), stderr: "" };
359
+ }
333
360
  const project = await loadProject(root);
334
361
  if (command === "register") {
335
362
  const result = await registerSource(root, project, {
@@ -2,7 +2,7 @@ import { canonicalValue, digestJson, validateJsonValue } from "./canonical-json.
2
2
  import { fail } from "./errors.mjs";
3
3
  import { normalizeRelativePath } from "./path-policy.mjs";
4
4
 
5
- export const PACKAGE_VERSION = "1.2.0";
5
+ export const PACKAGE_VERSION = "1.3.1";
6
6
  export const EXCHANGE_PROTOCOL_VERSION = 1;
7
7
  export const ACTION_PLAN_SCHEMA_VERSION = 1;
8
8
  export const REVIEW_BUNDLE_SCHEMA_VERSION = 1;
@@ -21,8 +21,8 @@ export const ACTION_KINDS = Object.freeze([
21
21
 
22
22
  export const COMMANDS = Object.freeze([
23
23
  "accept-source-change", "approve", "capabilities", "check", "context", "dashboard", "deprecate",
24
- "deprecate-source", "discover", "init", "preflight", "propose", "publish", "register", "review-source",
25
- "revise", "setup", "sync",
24
+ "deprecate-source", "discover", "init", "integration-review", "preflight", "propose", "publish", "register",
25
+ "review-source", "revise", "setup", "stage-context", "sync",
26
26
  ]);
27
27
 
28
28
  const ACTION_KIND_SET = new Set(ACTION_KINDS);
@@ -3,17 +3,10 @@ import { approvePendingItems, approveProposal } from "./approver.mjs";
3
3
  import { registerSource, buildItemProposal } from "./authoring.mjs";
4
4
  import { blockingContextFindings, checkProject } from "./checker.mjs";
5
5
  import { canonicalJson, digestJson, prettyCanonicalJson, sha256 } from "./canonical-json.mjs";
6
- import { DASHBOARD_SCHEMA_VERSION } from "./dashboard-model.mjs";
7
6
  import { ProjectContextError, fail } from "./errors.mjs";
8
7
  import {
9
- ACTION_KINDS,
10
- ACTION_PLAN_SCHEMA_VERSION,
11
8
  assertActionPlanConflictFree,
12
- CAPABILITIES_SCHEMA_VERSION,
13
- COMMANDS,
14
- EXCHANGE_PROTOCOL_VERSION,
15
9
  itemPrimitiveInput,
16
- PACKAGE_VERSION,
17
10
  REVIEW_BUNDLE_SCHEMA_VERSION,
18
11
  validateActionPlan,
19
12
  validateReviewBundle,
@@ -21,17 +14,12 @@ import {
21
14
  import { readJsonFile } from "./io.mjs";
22
15
  import { acceptSourceChange, deprecateItem, deprecateSource, reviewSource, reviseItem } from "./maintenance.mjs";
23
16
  import { resolveExistingInside, resolveWritableInside } from "./path-policy.mjs";
24
- import { inspectProjectInitialization, loadProject } from "./project-store.mjs";
17
+ import { loadProject } from "./project-store.mjs";
25
18
  import { publishProjection } from "./projection-store.mjs";
26
- import { RENDERER_VERSION } from "./renderer.mjs";
27
- import { ASSIST_BUNDLE_SCHEMA_VERSION } from "./assist.mjs";
19
+ export { buildCapabilities } from "./capabilities.mjs";
28
20
 
29
21
  const INTERNAL_AUTHORITY_SENTINEL = "exchange-preflight-not-authority";
30
22
  const INTERNAL_TIMESTAMP = "1970-01-01T00:00:00.000Z";
31
- const CONTRACT_SCHEMA_VERSION = 2;
32
- const PROPOSAL_SCHEMA_VERSION = 1;
33
- const SOURCE_LOCK_SCHEMA_VERSION = 1;
34
- const PROJECTION_LOCK_SCHEMA_VERSION = 1;
35
23
  const GROUP_BY_ACTION = new Map([
36
24
  ["accept-source-change", "source-change"],
37
25
  ["register-source", "source-change"],
@@ -47,52 +35,6 @@ function uniqueSorted(values) {
47
35
  return [...new Set(values)].sort((left, right) => left.localeCompare(right));
48
36
  }
49
37
 
50
- function schemas() {
51
- return {
52
- actionPlan: ACTION_PLAN_SCHEMA_VERSION,
53
- assistBundle: ASSIST_BUNDLE_SCHEMA_VERSION,
54
- capabilities: CAPABILITIES_SCHEMA_VERSION,
55
- contract: CONTRACT_SCHEMA_VERSION,
56
- dashboardViewModel: DASHBOARD_SCHEMA_VERSION,
57
- projectionLock: PROJECTION_LOCK_SCHEMA_VERSION,
58
- projectionRenderer: RENDERER_VERSION,
59
- proposal: PROPOSAL_SCHEMA_VERSION,
60
- reviewBundle: REVIEW_BUNDLE_SCHEMA_VERSION,
61
- sourceLock: SOURCE_LOCK_SCHEMA_VERSION,
62
- };
63
- }
64
-
65
- export async function buildCapabilities(root) {
66
- const initialization = await inspectProjectInitialization(root);
67
- let project = null;
68
- if (initialization.status === "initialized") {
69
- const loaded = await loadProject(root);
70
- project = { id: loaded.contract.project.id, name: loaded.contract.project.name };
71
- }
72
- return {
73
- schemaVersion: CAPABILITIES_SCHEMA_VERSION,
74
- package: { name: "frontend-project-context", version: PACKAGE_VERSION },
75
- exchangeProtocolVersion: EXCHANGE_PROTOCOL_VERSION,
76
- schemas: schemas(),
77
- commands: [...COMMANDS],
78
- actionKinds: [...ACTION_KINDS],
79
- initialization: initialization.status,
80
- initialized: initialization.status === "initialized",
81
- project,
82
- boundaries: {
83
- provider: false,
84
- agentRuntime: false,
85
- git: false,
86
- network: false,
87
- dependencyInstallation: false,
88
- automaticApproval: false,
89
- businessCodeWrites: false,
90
- applyPlan: false,
91
- scheduler: false,
92
- daemon: false,
93
- },
94
- };
95
- }
96
38
 
97
39
  function allProjectionPaths(project) {
98
40
  return project.projectionsLock.projections.map((entry) => entry.path).sort();