@c4a/context-cli 0.6.9 → 0.6.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/cli.js CHANGED
@@ -68074,7 +68074,7 @@ function proseStaleMessage(sourceRef, status) {
68074
68074
  }
68075
68075
  return `document source span changed for ${sourceRef}; create a replacement candidate unless the approved body still matches a moved source span`;
68076
68076
  }
68077
- async function loadVerifiedSymbolIndex(projectRoot) {
68077
+ async function loadVerifiedSymbolIndex(projectRoot, options = {}) {
68078
68078
  const symbolIndex = await readExtractSourceSymbolIndex(projectRoot);
68079
68079
  if (symbolIndex === null) {
68080
68080
  return {
@@ -68100,6 +68100,15 @@ async function loadVerifiedSymbolIndex(projectRoot) {
68100
68100
  unavailableMessage: `extract symbol index does not match source fingerprint cache for phase ${stalePhase[0]}; source_ref reverse lookup was skipped`
68101
68101
  };
68102
68102
  }
68103
+ const expectedPhaseIds = [...new Set(options.expectedPhaseIds ?? [])].sort();
68104
+ const missingPhaseIds = expectedPhaseIds.filter((phaseId) => symbolIndex.phaseFingerprints[phaseId] === undefined);
68105
+ if (missingPhaseIds.length > 0) {
68106
+ return {
68107
+ bySource: null,
68108
+ unavailableCode: "extract-symbol-index-incomplete",
68109
+ unavailableMessage: `extract symbol index covers ${expectedPhaseIds.length - missingPhaseIds.length}/${expectedPhaseIds.length} declared extraction phases; source_ref reverse lookup was deferred until extraction completes`
68110
+ };
68111
+ }
68103
68112
  const symbolIndexBySource = new Map;
68104
68113
  for (const symbol of symbolIndex.symbols) {
68105
68114
  const bucket = symbolIndexBySource.get(symbol.source) ?? [];
@@ -72640,7 +72649,16 @@ async function readCandidateDecisionState(input) {
72640
72649
  }
72641
72650
  async function verifyProjectWorkspace(projectRoot, options = {}) {
72642
72651
  const issues = [];
72643
- const symbolIndex = await loadVerifiedSymbolIndex(projectRoot);
72652
+ let expectedExtractPhaseIds = options.expectedExtractPhaseIds;
72653
+ if (expectedExtractPhaseIds === undefined) {
72654
+ try {
72655
+ const loaded = await loadContextProjectModule(projectRoot);
72656
+ expectedExtractPhaseIds = loaded.project.phases.filter((phase) => phase.kind === "phase.extract.ts" || phase.kind === "phase.extract.custom").map((phase) => phase.id);
72657
+ } catch {}
72658
+ }
72659
+ const symbolIndex = await loadVerifiedSymbolIndex(projectRoot, {
72660
+ ...expectedExtractPhaseIds === undefined ? {} : { expectedPhaseIds: expectedExtractPhaseIds }
72661
+ });
72644
72662
  const sourceRegistry = await loadSourceRegistryLookup(projectRoot, issues);
72645
72663
  const evidenceIndexCache = {
72646
72664
  entries: new Map,
@@ -87183,10 +87201,12 @@ async function readSourceStatus(projectRoot) {
87183
87201
  diagnostics
87184
87202
  };
87185
87203
  }
87186
- async function readVerifyStatus(projectRoot) {
87204
+ async function readVerifyStatus(projectRoot, expectedExtractPhaseIds) {
87187
87205
  try {
87188
87206
  return {
87189
- issues: (await verifyProjectWorkspace(projectRoot)).issues,
87207
+ issues: (await verifyProjectWorkspace(projectRoot, {
87208
+ ...expectedExtractPhaseIds === undefined ? {} : { expectedExtractPhaseIds }
87209
+ })).issues,
87190
87210
  diagnostics: []
87191
87211
  };
87192
87212
  } catch (error) {
@@ -87734,6 +87754,10 @@ function evidenceMaintenanceClear(observation) {
87734
87754
  return true;
87735
87755
  if (verifyErrorsAreCloseRepairable(observation.verifyIssues))
87736
87756
  return true;
87757
+ const staleEvidenceIssues = observation.verifyIssues.filter((issue) => issue.severity === "error" && issue.code === "approved-source-ref-stale");
87758
+ const pendingExtractionRepairsCodeEvidence = observation.pendingExtractPhases.length > 0 && staleEvidenceIssues.length > 0 && staleEvidenceIssues.every((issue) => issue.source_keys !== undefined && issue.source_keys.length > 0 && issue.source_keys.every((sourceKey) => sourceKey.startsWith("repo:")));
87759
+ if (pendingExtractionRepairsCodeEvidence)
87760
+ return true;
87737
87761
  return observation.evidenceWarnings !== "orphaned" && observation.evidenceWarnings !== "stale";
87738
87762
  }
87739
87763
  function proseDeclarationsComplete(observation) {
@@ -89296,7 +89320,7 @@ async function collectProjectStatusSnapshot(projectRoot, options = {}) {
89296
89320
  sources,
89297
89321
  sourceStatuses
89298
89322
  }) : { state: "ready", stalePhases: [], pendingPhases: [], diagnostics: [], errorDiagnostics: [] };
89299
- const verifyStatus = draftStatus.diagnostics.length === 0 ? await readVerifyStatus(projectRoot) : { issues: [], diagnostics: [] };
89323
+ const verifyStatus = draftStatus.diagnostics.length === 0 ? await readVerifyStatus(projectRoot, phases.filter((phase) => phase.kind === "phase.extract.ts" || phase.kind === "phase.extract.custom").map((phase) => phase.id)) : { issues: [], diagnostics: [] };
89300
89324
  const resourceRepair = resourcePlaceholderRepairTargets(verifyStatus.issues);
89301
89325
  const pendingCapture = pendingDocumentCaptureCommands({
89302
89326
  phases,
@@ -104479,17 +104503,27 @@ function parseRepositoryRecoveryPayload(value) {
104479
104503
  });
104480
104504
  return { schema: RECOVERY_SCHEMA, repositories };
104481
104505
  }
104482
- function canonicalRemote(value) {
104506
+ function trimRepositorySuffix(value) {
104507
+ return value.trim().replace(/^\/+|\/+$/gu, "").replace(/\.git$/iu, "");
104508
+ }
104509
+ function repositoryPathIdentity(value) {
104483
104510
  const trimmed = value.trim().replace(/\/+$/u, "").replace(/\.git$/iu, "");
104484
- const scp = /^(?:[^@]+@)?([^:]+):(.+)$/u.exec(trimmed);
104485
- if (scp !== null)
104486
- return `${scp[1]?.toLowerCase()}/${scp[2]}`;
104487
- try {
104488
- const url = new URL(trimmed);
104489
- return `${url.hostname.toLowerCase()}${url.pathname}`.replace(/\/+$/u, "").replace(/\.git$/iu, "");
104490
- } catch {
104491
- return trimmed;
104511
+ const windowsPath = /^[a-z]:[\\/]/iu.test(trimmed);
104512
+ const urlSyntax = /^[a-z][a-z0-9+.-]*:\/\//iu.test(trimmed);
104513
+ if (!windowsPath && urlSyntax) {
104514
+ try {
104515
+ const url = new URL(trimmed);
104516
+ if (url.hostname.length > 0)
104517
+ return trimRepositorySuffix(url.pathname);
104518
+ return url.pathname.replace(/\/+$/u, "").replace(/\.git$/iu, "");
104519
+ } catch {
104520
+ return trimmed;
104521
+ }
104492
104522
  }
104523
+ const scp = windowsPath ? null : /^(?:[^@/:]+@)?[^/:]+:(.+)$/u.exec(trimmed);
104524
+ if (scp?.[1] !== undefined)
104525
+ return trimRepositorySuffix(scp[1]);
104526
+ return trimmed;
104493
104527
  }
104494
104528
  function repositorySlug(remote) {
104495
104529
  const raw = basename9(remote.replace(/\/+$/u, "").replace(/\.git$/iu, ""));
@@ -104500,7 +104534,7 @@ function groupId(source2) {
104500
104534
  return `${repositorySlug(source2.git.remote)}-${source2.git.ref.slice(0, 12)}`;
104501
104535
  }
104502
104536
  function groupKey(source2) {
104503
- return `${canonicalRemote(source2.git.remote)}\x00${source2.git.ref.toLowerCase()}`;
104537
+ return `${repositoryPathIdentity(source2.git.remote)}\x00${source2.git.ref.toLowerCase()}`;
104504
104538
  }
104505
104539
  function suggestedCloneTarget(source2) {
104506
104540
  return `.tmp/repo/${groupId(source2)}`;
@@ -104580,10 +104614,14 @@ async function resolveGitRoot2(path4) {
104580
104614
  }
104581
104615
  async function verifyCheckout(input) {
104582
104616
  const actualRemote = await git2(input.checkout, ["remote", "get-url", "origin"]);
104583
- if (canonicalRemote(actualRemote) !== canonicalRemote(input.remote)) {
104617
+ const expectedRepository = repositoryPathIdentity(input.remote);
104618
+ const actualRepository = repositoryPathIdentity(actualRemote);
104619
+ if (actualRepository !== expectedRepository) {
104584
104620
  throw userInputError3("local repository origin does not match the registered source", {
104585
104621
  expected_remote: input.remote,
104586
104622
  actual_remote: actualRemote,
104623
+ expected_repository: expectedRepository,
104624
+ actual_repository: actualRepository,
104587
104625
  checkout: input.checkout
104588
104626
  });
104589
104627
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@c4a/context-cli",
3
- "version": "0.6.9",
3
+ "version": "0.6.11",
4
4
  "type": "module",
5
5
  "description": "Local runtime and Agent integration for traceable knowledge production",
6
6
  "license": "MIT",
@@ -24,7 +24,7 @@
24
24
  },
25
25
  "dependencies": {
26
26
  "@c4a/agent-graph": "0.2.6",
27
- "@c4a/context": "0.6.9",
27
+ "@c4a/context": "0.6.11",
28
28
  "commander": "^11.0.0",
29
29
  "fast-xml-parser": "^5.10.1",
30
30
  "handlebars": "^4.7.8",
package/plugins/VERSION CHANGED
@@ -1 +1 @@
1
- 0.6.9
1
+ 0.6.11
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "c4a",
3
3
  "description": "Start or continue a project-local knowledge workspace through one graph-routed entry.",
4
- "version": "0.6.9",
4
+ "version": "0.6.11",
5
5
  "author": {
6
6
  "name": "c4a"
7
7
  },
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "c4a",
3
- "version": "0.6.9",
3
+ "version": "0.6.11",
4
4
  "description": "Start or continue a project-local knowledge workspace through one graph-routed entry.",
5
5
  "author": {
6
6
  "name": "c4a"
@@ -18,7 +18,7 @@
18
18
  "skills": "./skills/",
19
19
  "interface": {
20
20
  "displayName": "C4A Context",
21
- "shortDescription": "Initialize and advance a local, source-linked project knowledge workspace.\nv0.6.9",
21
+ "shortDescription": "Initialize and advance a local, source-linked project knowledge workspace.\nv0.6.11",
22
22
  "longDescription": "Create a Context workspace and use agent-guided next steps to register sources, run extraction, review candidates, build package outputs, and verify health without silently mutating source repositories.",
23
23
  "developerName": "c4a",
24
24
  "category": "Productivity",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "c4a",
3
3
  "displayName": "C4A Context",
4
- "version": "0.6.9",
4
+ "version": "0.6.11",
5
5
  "description": "Start or continue a project-local knowledge workspace through one graph-routed entry.",
6
6
  "author": {
7
7
  "name": "Context4AI",
@@ -2,7 +2,7 @@
2
2
  "schema": "agent-graph.bundle.v1",
3
3
  "provider": {
4
4
  "id": "c4a/context",
5
- "version": "0.6.9"
5
+ "version": "0.6.11"
6
6
  },
7
7
  "providerManifest": "provider.yaml",
8
8
  "graphs": [
@@ -532,7 +532,7 @@
532
532
  },
533
533
  {
534
534
  "path": "provider.yaml",
535
- "digest": "sha256:ef4af3314dc2d10892d97f0236d68b8a3b7549cfbcb5c55c45efc3de08b2a50e"
535
+ "digest": "sha256:f89e3a74b6c752aaabbad5b5774d3687a7fb5419894f30741129b71419d234d4"
536
536
  },
537
537
  {
538
538
  "path": "resources/diagnostics/projection-stale.md",
@@ -750,5 +750,5 @@
750
750
  "graphDependencies": {
751
751
  "workspace": []
752
752
  },
753
- "digest": "sha256:3550fa7734792eb9bcc2abacf04f7fff9c0ac14344bbecea3a2b961f1354c8b3"
753
+ "digest": "sha256:15058859f3884290c2c88de136633c2fbfb16e1a69d1a55796d92dc9082cdb94"
754
754
  }
@@ -1,6 +1,6 @@
1
1
  schema: agent-graph.provider.v1
2
2
  id: c4a/context
3
- version: 0.6.9
3
+ version: 0.6.11
4
4
  name: Context workflow
5
5
  description: Internal work contract for Context knowledge workspaces.
6
6
  graphs: