@c4a/context-cli 0.6.8 → 0.6.9
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/README.md +156 -220
- package/README.zh-CN.md +120 -160
- package/cli.js +240 -47
- package/docs/quickstart.md +57 -70
- package/docs/quickstart.zh-CN.md +79 -0
- package/package.json +4 -4
- package/plugins/.agents/plugins/marketplace.json +1 -1
- package/plugins/.claude-plugin/marketplace.json +2 -2
- package/plugins/.cursor-plugin/marketplace.json +2 -2
- package/plugins/README.md +79 -66
- package/plugins/README_CN.md +62 -57
- package/plugins/VERSION +1 -1
- package/plugins/claude/.claude-plugin/plugin.json +3 -3
- package/plugins/claude/commands/context.md +121 -0
- package/plugins/codex/.codex-plugin/plugin.json +4 -4
- package/plugins/codex/skills/context/SKILL.md +133 -0
- package/plugins/cursor/.cursor-plugin/plugin.json +3 -3
- package/plugins/cursor/README.md +2 -2
- package/plugins/cursor/commands/c4a-context.md +125 -0
- package/plugins/skills/c4a-context/SKILL.md +133 -0
- package/providers/context/graphs/workspace.yaml +40 -1
- package/providers/context/manifest.json +27 -9
- package/providers/context/provider.yaml +2 -2
- package/providers/context/resources/dialogue/workflow-mode-after-capture.md +22 -0
- package/providers/context/resources/dialogue/workflow-mode-after-creation.md +25 -0
- package/providers/context/resources/manuals/guides/package-outputs.md +1 -1
- package/providers/context/resources/manuals/reference/package-templates.md +1 -1
- package/plugins/claude/commands/continue.md +0 -109
- package/plugins/claude/commands/init.md +0 -36
- package/plugins/codex/skills/continue/SKILL.md +0 -121
- package/plugins/codex/skills/init/SKILL.md +0 -48
- package/plugins/cursor/commands/context-continue.md +0 -113
- package/plugins/cursor/commands/context-init.md +0 -40
- package/plugins/skills/context-continue/SKILL.md +0 -121
- package/plugins/skills/context-init/SKILL.md +0 -48
package/cli.js
CHANGED
|
@@ -17554,7 +17554,7 @@ async function recordAgentGraphEvaluation(input) {
|
|
|
17554
17554
|
...input.route === undefined ? {} : { routeId: input.route.id, node: input.route.node, reasonCode: input.route.reasonCode }
|
|
17555
17555
|
};
|
|
17556
17556
|
await appendEvent(input.projectRoot, "agent-graph.evaluated", {
|
|
17557
|
-
graph: { provider: "c4a/context", graph: "workspace", entry: "
|
|
17557
|
+
graph: { provider: "c4a/context", graph: "workspace", entry: "context" },
|
|
17558
17558
|
current: current2,
|
|
17559
17559
|
...input.route === undefined ? {} : { selected_route: input.route },
|
|
17560
17560
|
alternatives: input.alternatives
|
|
@@ -24130,7 +24130,7 @@ var require_lib = __commonJS((exports, module) => {
|
|
|
24130
24130
|
});
|
|
24131
24131
|
|
|
24132
24132
|
// src/cli.ts
|
|
24133
|
-
import { existsSync as
|
|
24133
|
+
import { existsSync as existsSync47, readFileSync as readFileSync10, realpathSync } from "node:fs";
|
|
24134
24134
|
import { dirname as dirname42, join as join71 } from "node:path";
|
|
24135
24135
|
import { fileURLToPath as fileURLToPath10, pathToFileURL as pathToFileURL4 } from "node:url";
|
|
24136
24136
|
|
|
@@ -24162,7 +24162,7 @@ init_exitCode();
|
|
|
24162
24162
|
// src/project/workflow/workflowTypes.ts
|
|
24163
24163
|
var CONTEXT_WORKFLOW_PROVIDER_ID = "c4a/context";
|
|
24164
24164
|
var CONTEXT_WORKFLOW_GRAPH_ID = "workspace";
|
|
24165
|
-
var CONTEXT_WORKFLOW_ENTRY = "
|
|
24165
|
+
var CONTEXT_WORKFLOW_ENTRY = "context";
|
|
24166
24166
|
var CONTEXT_WORKFLOW_AUTHORITIES = {
|
|
24167
24167
|
evidenceMaintenance: "context.evidence-maintenance",
|
|
24168
24168
|
repositoryRestore: "context.repository-restore",
|
|
@@ -24198,7 +24198,7 @@ function mergedWorkflowAuthorities(...values) {
|
|
|
24198
24198
|
// src/project/workflow/workflowResource.ts
|
|
24199
24199
|
import { join as join57 } from "node:path";
|
|
24200
24200
|
|
|
24201
|
-
// ../../node_modules/.bun/@c4a+agent-graph@0.2.
|
|
24201
|
+
// ../../node_modules/.bun/@c4a+agent-graph@0.2.6/node_modules/@c4a/agent-graph/dist/index.js
|
|
24202
24202
|
import { createRequire as createRequire2 } from "node:module";
|
|
24203
24203
|
import { createHash } from "node:crypto";
|
|
24204
24204
|
import { mkdir, readFile, readdir, realpath, rename, stat, writeFile } from "node:fs/promises";
|
|
@@ -38749,6 +38749,15 @@ var graph_schema_default = {
|
|
|
38749
38749
|
},
|
|
38750
38750
|
inspectionAction: { $ref: "#/$defs/relativePath" },
|
|
38751
38751
|
resolutionAction: { $ref: "#/$defs/relativePath" },
|
|
38752
|
+
delegated: {
|
|
38753
|
+
type: "object",
|
|
38754
|
+
additionalProperties: false,
|
|
38755
|
+
properties: {
|
|
38756
|
+
inspection: { enum: ["required", "skip"], default: "required" },
|
|
38757
|
+
resolutionAction: { $ref: "#/$defs/relativePath" },
|
|
38758
|
+
resources: { $ref: "#/$defs/resources" }
|
|
38759
|
+
}
|
|
38760
|
+
},
|
|
38752
38761
|
terminalOutcome: { $ref: "#/$defs/outcome" },
|
|
38753
38762
|
requiresFacts: { type: "array", items: { $ref: "#/$defs/factCheck" } },
|
|
38754
38763
|
satisfiedBy: { type: "array", minItems: 1, items: { $ref: "#/$defs/factCheck" } },
|
|
@@ -38758,7 +38767,7 @@ var graph_schema_default = {
|
|
|
38758
38767
|
{
|
|
38759
38768
|
properties: { kind: { const: "action" } },
|
|
38760
38769
|
required: ["action", "reasonCode"],
|
|
38761
|
-
not: { anyOf: [{ required: ["graph"] }, { required: ["entry"] }, { required: ["gate"] }, { required: ["inspectionAction"] }, { required: ["resolutionAction"] }, { required: ["terminalOutcome"] }] }
|
|
38770
|
+
not: { anyOf: [{ required: ["graph"] }, { required: ["entry"] }, { required: ["gate"] }, { required: ["inspectionAction"] }, { required: ["resolutionAction"] }, { required: ["delegated"] }, { required: ["terminalOutcome"] }] }
|
|
38762
38771
|
},
|
|
38763
38772
|
{
|
|
38764
38773
|
properties: { kind: { const: "gate" } },
|
|
@@ -38768,12 +38777,12 @@ var graph_schema_default = {
|
|
|
38768
38777
|
{
|
|
38769
38778
|
properties: { kind: { const: "subgraph" } },
|
|
38770
38779
|
required: ["graph", "entry"],
|
|
38771
|
-
not: { anyOf: [{ required: ["action"] }, { required: ["gate"] }, { required: ["inspectionAction"] }, { required: ["resolutionAction"] }, { required: ["reasonCode"] }, { required: ["terminalOutcome"] }, { required: ["satisfiedBy"] }, { required: ["resources"] }] }
|
|
38780
|
+
not: { anyOf: [{ required: ["action"] }, { required: ["gate"] }, { required: ["inspectionAction"] }, { required: ["resolutionAction"] }, { required: ["delegated"] }, { required: ["reasonCode"] }, { required: ["terminalOutcome"] }, { required: ["satisfiedBy"] }, { required: ["resources"] }] }
|
|
38772
38781
|
},
|
|
38773
38782
|
{
|
|
38774
38783
|
properties: { kind: { const: "terminal" } },
|
|
38775
38784
|
required: ["terminalOutcome"],
|
|
38776
|
-
not: { anyOf: [{ required: ["action"] }, { required: ["graph"] }, { required: ["entry"] }, { required: ["gate"] }, { required: ["inspectionAction"] }, { required: ["resolutionAction"] }, { required: ["reasonCode"] }, { required: ["satisfiedBy"] }, { required: ["resources"] }] }
|
|
38785
|
+
not: { anyOf: [{ required: ["action"] }, { required: ["graph"] }, { required: ["entry"] }, { required: ["gate"] }, { required: ["inspectionAction"] }, { required: ["resolutionAction"] }, { required: ["delegated"] }, { required: ["reasonCode"] }, { required: ["satisfiedBy"] }, { required: ["resources"] }] }
|
|
38777
38786
|
}
|
|
38778
38787
|
]
|
|
38779
38788
|
},
|
|
@@ -39854,6 +39863,20 @@ async function loadProvider(manifestPath) {
|
|
|
39854
39863
|
throw new AgentGraphError("gate-inspection-effect-invalid", `Gate ${graphId}/${node.id} inspection Action ${inspection.definition.id} must use effect: read`);
|
|
39855
39864
|
}
|
|
39856
39865
|
}
|
|
39866
|
+
if (node.kind === "gate" && node.delegated !== undefined) {
|
|
39867
|
+
if (node.gate.delegatable !== true || node.gate.authority === undefined) {
|
|
39868
|
+
throw new AgentGraphError("gate-delegated-policy-invalid", `Gate ${graphId}/${node.id} declares delegated execution without a delegatable authority`);
|
|
39869
|
+
}
|
|
39870
|
+
if (node.delegated.inspection === "skip" && node.inspectionAction === undefined) {
|
|
39871
|
+
throw new AgentGraphError("gate-delegated-inspection-missing", `Gate ${graphId}/${node.id} skips delegated inspection but has no inspection Action`);
|
|
39872
|
+
}
|
|
39873
|
+
if (node.delegated.resolutionAction !== undefined) {
|
|
39874
|
+
const delegatedResolution = await includeAction(node.delegated.resolutionAction, directFiles, "delegated gate resolution action referenced file");
|
|
39875
|
+
if (delegatedResolution.definition.effect === "read") {
|
|
39876
|
+
throw new AgentGraphError("gate-resolution-effect-invalid", `Gate ${graphId}/${node.id} delegated resolution Action ${delegatedResolution.definition.id} must use effect: write or external`);
|
|
39877
|
+
}
|
|
39878
|
+
}
|
|
39879
|
+
}
|
|
39857
39880
|
if (node.kind === "gate" && node.resolutionAction) {
|
|
39858
39881
|
const resolution = await includeAction(node.resolutionAction, directFiles, "gate resolution action referenced file");
|
|
39859
39882
|
if (resolution.definition.effect === "read") {
|
|
@@ -39861,9 +39884,12 @@ async function loadProvider(manifestPath) {
|
|
|
39861
39884
|
}
|
|
39862
39885
|
}
|
|
39863
39886
|
const nodeResources = node.kind === "action" || node.kind === "gate" ? node.resources : undefined;
|
|
39887
|
+
const delegatedResources = node.kind === "gate" ? node.delegated?.resources : undefined;
|
|
39864
39888
|
for (const resourceReference of [
|
|
39865
39889
|
...nodeResources?.required ?? [],
|
|
39866
|
-
...nodeResources?.recommended ?? []
|
|
39890
|
+
...nodeResources?.recommended ?? [],
|
|
39891
|
+
...delegatedResources?.required ?? [],
|
|
39892
|
+
...delegatedResources?.recommended ?? []
|
|
39867
39893
|
]) {
|
|
39868
39894
|
const resourcePath = resolveContainedPath(root, resourceReference, "resource reference");
|
|
39869
39895
|
if (!resources.has(resourcePath)) {
|
|
@@ -40113,8 +40139,9 @@ async function locateCode(provider, code) {
|
|
|
40113
40139
|
};
|
|
40114
40140
|
}
|
|
40115
40141
|
async function resourcesForCandidate(provider, candidate, revision) {
|
|
40116
|
-
const
|
|
40117
|
-
const
|
|
40142
|
+
const selectedResources = candidate.node.kind === "gate" && candidate.gateResolution === "session-authority" && candidate.node.delegated?.resources !== undefined ? candidate.node.delegated.resources : candidate.node.resources;
|
|
40143
|
+
const requiredReferences = [...selectedResources?.required ?? []];
|
|
40144
|
+
const recommendedReferences = [...selectedResources?.recommended ?? []];
|
|
40118
40145
|
const action = candidate.node.kind === "action" ? referencedAction(provider, candidate.node.action) : undefined;
|
|
40119
40146
|
const required = await Promise.all(requiredReferences.map((reference) => locateResource(provider, reference, revision)));
|
|
40120
40147
|
const recommended = await Promise.all(recommendedReferences.map((reference) => locateResource(provider, reference, revision)));
|
|
@@ -40179,8 +40206,8 @@ async function resolveRoute(provider, graphId, entry2, routeId2, input = {}, exp
|
|
|
40179
40206
|
recommended: annotateReadState(locatedResources.recommended, input.resourceReceipts)
|
|
40180
40207
|
};
|
|
40181
40208
|
const action = candidate.node.kind === "action" ? referencedAction(provider, candidate.node.action) : undefined;
|
|
40182
|
-
const inspectionAction = candidate.node.kind === "gate" ? referencedAction(provider, candidate.node.inspectionAction) : undefined;
|
|
40183
|
-
const resolutionAction = candidate.node.kind === "gate" ? referencedAction(provider, candidate.node.resolutionAction) : undefined;
|
|
40209
|
+
const inspectionAction = candidate.node.kind === "gate" && !(candidate.gateResolution === "session-authority" && candidate.node.delegated?.inspection === "skip") ? referencedAction(provider, candidate.node.inspectionAction) : undefined;
|
|
40210
|
+
const resolutionAction = candidate.node.kind === "gate" ? referencedAction(provider, candidate.gateResolution === "session-authority" && candidate.node.delegated?.resolutionAction !== undefined ? candidate.node.delegated.resolutionAction : candidate.node.resolutionAction) : undefined;
|
|
40184
40211
|
const workspace = input.workspace ?? process.cwd();
|
|
40185
40212
|
return {
|
|
40186
40213
|
schema: "agent-graph.route.v1",
|
|
@@ -69148,6 +69175,7 @@ var RUNTIME_EVENT_STATE_SCHEMA = "context.runtime-event-state.v1";
|
|
|
69148
69175
|
var RUNTIME_EVENT_STATE_FILE = "runtime-event-state.json";
|
|
69149
69176
|
var RUNTIME_EVENT_SINK_DESCRIPTION_TIMEOUT_MS = 2000;
|
|
69150
69177
|
var RUNTIME_EVENT_SINK_DESCRIPTION_MAX_BYTES = 16 * 1024;
|
|
69178
|
+
var RUNTIME_EVENTS_DISABLED_ENV = "CONTEXT_RUNTIME_EVENTS_DISABLED";
|
|
69151
69179
|
var activeScope;
|
|
69152
69180
|
function isRecord9(value) {
|
|
69153
69181
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
@@ -69256,7 +69284,7 @@ function readRuntimePackageMetadata() {
|
|
|
69256
69284
|
if (isRecord9(parsed)) {
|
|
69257
69285
|
return {
|
|
69258
69286
|
contextVersion: typeof parsed.version === "string" ? parsed.version : "unknown",
|
|
69259
|
-
sink: parseContextRuntimeEventSink(parsed.contextRuntimeEventSink)
|
|
69287
|
+
sink: process.env[RUNTIME_EVENTS_DISABLED_ENV] === "1" ? null : parseContextRuntimeEventSink(parsed.contextRuntimeEventSink)
|
|
69260
69288
|
};
|
|
69261
69289
|
}
|
|
69262
69290
|
}
|
|
@@ -87881,17 +87909,17 @@ function createContextWorkflowFacts(observation, authorities) {
|
|
|
87881
87909
|
source_read_resolved: captureComplete || hasAuthority(authorities, CONTEXT_WORKFLOW_AUTHORITIES.sourceRead),
|
|
87882
87910
|
extraction_scope_resolved: extractDeclarationsComplete,
|
|
87883
87911
|
document_classification_resolved: documentsClassified,
|
|
87884
|
-
structure_confirmation_resolved: structureConfirmed
|
|
87885
|
-
knowledge_review_resolved: reviewGateIsClear
|
|
87912
|
+
structure_confirmation_resolved: structureConfirmed,
|
|
87913
|
+
knowledge_review_resolved: reviewGateIsClear,
|
|
87886
87914
|
package_output_resolved: packagesDeclared || hasAuthority(authorities, CONTEXT_WORKFLOW_AUTHORITIES.packageOutput)
|
|
87887
87915
|
},
|
|
87888
87916
|
resume: {
|
|
87889
87917
|
prose_declarations_complete: !captureComplete || !documentRoundStarted || activeRoundProseComplete,
|
|
87890
87918
|
...structureRefreshRequired ? { structure_refresh_required: true } : {},
|
|
87891
|
-
structure_confirmation_resolved: !captureComplete || !documentRoundStarted || structureConfirmed
|
|
87919
|
+
structure_confirmation_resolved: !captureComplete || !documentRoundStarted || structureConfirmed,
|
|
87892
87920
|
structure_confirmed: !captureComplete || !documentRoundStarted || structureConfirmed,
|
|
87893
87921
|
compile_complete: !captureComplete || !documentRoundStarted || compiled,
|
|
87894
|
-
knowledge_review_resolved: !captureComplete || !documentRoundStarted || reviewGateIsClear
|
|
87922
|
+
knowledge_review_resolved: !captureComplete || !documentRoundStarted || reviewGateIsClear,
|
|
87895
87923
|
review_gate_clear: !captureComplete || !documentRoundStarted || reviewGateIsClear
|
|
87896
87924
|
},
|
|
87897
87925
|
sources: {
|
|
@@ -88927,11 +88955,12 @@ function withContentAddressedWorkflowResources(status, receipts) {
|
|
|
88927
88955
|
|
|
88928
88956
|
// src/project/workflow/workflowStatusProjection.ts
|
|
88929
88957
|
function pendingReview(observation, route) {
|
|
88930
|
-
const decisionSource = route?.
|
|
88958
|
+
const decisionSource = route?.gate?.id === "knowledge-review" ? route.gate.resolution === "session-authority" ? "managed-session" : "user-review" : route?.reason_code === "route.review.apply-managed" ? "managed-session" : undefined;
|
|
88931
88959
|
if (decisionSource === undefined || observation.draftCandidates <= 0 || observation.draftCollections.length === 0) {
|
|
88932
88960
|
return;
|
|
88933
88961
|
}
|
|
88934
88962
|
const collections = [...observation.draftCollections];
|
|
88963
|
+
const managedCommand = decisionSource === "managed-session" ? route?.commands.find((item) => item.availability === "immediate" && item.effect === "write")?.command : undefined;
|
|
88935
88964
|
if (collections.length === 1) {
|
|
88936
88965
|
const collection = collections[0];
|
|
88937
88966
|
return {
|
|
@@ -88939,7 +88968,7 @@ function pendingReview(observation, route) {
|
|
|
88939
88968
|
collections,
|
|
88940
88969
|
collection,
|
|
88941
88970
|
count: observation.draftCandidates,
|
|
88942
|
-
command: `context review html ${collection} --open`,
|
|
88971
|
+
command: managedCommand ?? `context review html ${collection} --open`,
|
|
88943
88972
|
decisionSource,
|
|
88944
88973
|
...observation.candidateSetDigest === undefined ? {} : { candidateSetDigest: observation.candidateSetDigest }
|
|
88945
88974
|
};
|
|
@@ -88948,7 +88977,7 @@ function pendingReview(observation, route) {
|
|
|
88948
88977
|
scope: "all",
|
|
88949
88978
|
collections,
|
|
88950
88979
|
count: observation.draftCandidates,
|
|
88951
|
-
command: "context review html --all --open",
|
|
88980
|
+
command: managedCommand ?? "context review html --all --open",
|
|
88952
88981
|
decisionSource,
|
|
88953
88982
|
...observation.candidateSetDigest === undefined ? {} : { candidateSetDigest: observation.candidateSetDigest }
|
|
88954
88983
|
};
|
|
@@ -106258,6 +106287,153 @@ init_cliFeedback();
|
|
|
106258
106287
|
init_errors();
|
|
106259
106288
|
init_workspace();
|
|
106260
106289
|
init_exitCode();
|
|
106290
|
+
|
|
106291
|
+
// src/project/entryCommand.ts
|
|
106292
|
+
init_workspace();
|
|
106293
|
+
import { existsSync as existsSync45 } from "node:fs";
|
|
106294
|
+
import { resolve as resolve30 } from "node:path";
|
|
106295
|
+
function shellQuote9(value) {
|
|
106296
|
+
return /^[A-Za-z0-9._/=-]+$/u.test(value) ? value : `'${value.replaceAll("'", `'"'"'`)}'`;
|
|
106297
|
+
}
|
|
106298
|
+
function workflowCommand(input) {
|
|
106299
|
+
const authorities = input.authorities ?? [];
|
|
106300
|
+
if (input.managed === true) {
|
|
106301
|
+
return [
|
|
106302
|
+
"context run --managed --until blocked-or-complete --format json",
|
|
106303
|
+
...authorities.map((authority) => `--authority ${shellQuote9(authority)}`)
|
|
106304
|
+
].join(" ");
|
|
106305
|
+
}
|
|
106306
|
+
return [
|
|
106307
|
+
"context status --format json",
|
|
106308
|
+
...authorities.map((authority) => `--authority ${shellQuote9(authority)}`)
|
|
106309
|
+
].join(" ");
|
|
106310
|
+
}
|
|
106311
|
+
function initCommand2(input, projectDir) {
|
|
106312
|
+
const args = [
|
|
106313
|
+
"context",
|
|
106314
|
+
"init",
|
|
106315
|
+
projectDir,
|
|
106316
|
+
"--language",
|
|
106317
|
+
input.language
|
|
106318
|
+
];
|
|
106319
|
+
if (input.name !== undefined)
|
|
106320
|
+
args.push("--name", input.name);
|
|
106321
|
+
if (input.dev === true)
|
|
106322
|
+
args.push("--dev");
|
|
106323
|
+
if (input.debug === true)
|
|
106324
|
+
args.push("--debug");
|
|
106325
|
+
return args.map(shellQuote9).join(" ");
|
|
106326
|
+
}
|
|
106327
|
+
function readyResult(input, projectRoot, relocation) {
|
|
106328
|
+
const command2 = workflowCommand(input);
|
|
106329
|
+
return {
|
|
106330
|
+
schema: "context.entry.v1",
|
|
106331
|
+
state: relocation ? "workspace-relocation-required" : "workspace-ready",
|
|
106332
|
+
cwd: resolve30(input.cwd),
|
|
106333
|
+
workspace: {
|
|
106334
|
+
root: projectRoot,
|
|
106335
|
+
exists: true
|
|
106336
|
+
},
|
|
106337
|
+
next_action: {
|
|
106338
|
+
kind: relocation ? "enter-workspace" : "evaluate-workflow",
|
|
106339
|
+
command: relocation ? `cd ${shellQuote9(projectRoot)} && ${command2}` : command2,
|
|
106340
|
+
effect: "read",
|
|
106341
|
+
confirmation: "not-required"
|
|
106342
|
+
}
|
|
106343
|
+
};
|
|
106344
|
+
}
|
|
106345
|
+
function resolveContextEntry(input) {
|
|
106346
|
+
const cwd = resolve30(input.cwd);
|
|
106347
|
+
if (input.projectDir !== undefined) {
|
|
106348
|
+
const target2 = resolveContextProjectInitTarget(cwd, input.projectDir);
|
|
106349
|
+
if (existsSync45(target2) && isContextProjectRoot(target2)) {
|
|
106350
|
+
return readyResult(input, target2, target2 !== cwd);
|
|
106351
|
+
}
|
|
106352
|
+
return {
|
|
106353
|
+
schema: "context.entry.v1",
|
|
106354
|
+
state: "workspace-initialization-required",
|
|
106355
|
+
cwd,
|
|
106356
|
+
workspace: {
|
|
106357
|
+
root: target2,
|
|
106358
|
+
exists: existsSync45(target2)
|
|
106359
|
+
},
|
|
106360
|
+
next_action: {
|
|
106361
|
+
kind: "initialize-workspace",
|
|
106362
|
+
command: initCommand2(input, input.projectDir),
|
|
106363
|
+
effect: "write",
|
|
106364
|
+
confirmation: "required-unless-explicitly-requested"
|
|
106365
|
+
}
|
|
106366
|
+
};
|
|
106367
|
+
}
|
|
106368
|
+
const found = findContextProjectRoot(cwd);
|
|
106369
|
+
if (found !== null)
|
|
106370
|
+
return readyResult(input, found.projectRoot, false);
|
|
106371
|
+
const expectation = findContextWorkspaceExpectation(cwd);
|
|
106372
|
+
if (expectation !== null) {
|
|
106373
|
+
if (expectation.exists && isContextProjectRoot(expectation.workspaceRoot)) {
|
|
106374
|
+
return readyResult(input, expectation.workspaceRoot, true);
|
|
106375
|
+
}
|
|
106376
|
+
return {
|
|
106377
|
+
schema: "context.entry.v1",
|
|
106378
|
+
state: "workspace-initialization-required",
|
|
106379
|
+
cwd,
|
|
106380
|
+
workspace: {
|
|
106381
|
+
root: expectation.workspaceRoot,
|
|
106382
|
+
exists: expectation.exists
|
|
106383
|
+
},
|
|
106384
|
+
next_action: {
|
|
106385
|
+
kind: "initialize-workspace",
|
|
106386
|
+
command: `cd ${shellQuote9(expectation.markerRoot)} && ${initCommand2(input, expectation.workspaceDir)}`,
|
|
106387
|
+
effect: "write",
|
|
106388
|
+
confirmation: "required-unless-explicitly-requested"
|
|
106389
|
+
}
|
|
106390
|
+
};
|
|
106391
|
+
}
|
|
106392
|
+
const target = resolveContextProjectInitTarget(cwd, undefined);
|
|
106393
|
+
if (isContextProjectRoot(target)) {
|
|
106394
|
+
return readyResult(input, target, true);
|
|
106395
|
+
}
|
|
106396
|
+
return {
|
|
106397
|
+
schema: "context.entry.v1",
|
|
106398
|
+
state: "workspace-initialization-required",
|
|
106399
|
+
cwd,
|
|
106400
|
+
workspace: {
|
|
106401
|
+
root: target,
|
|
106402
|
+
exists: existsSync45(target)
|
|
106403
|
+
},
|
|
106404
|
+
next_action: {
|
|
106405
|
+
kind: "initialize-workspace",
|
|
106406
|
+
command: initCommand2(input, "context"),
|
|
106407
|
+
effect: "write",
|
|
106408
|
+
confirmation: "required-unless-explicitly-requested"
|
|
106409
|
+
}
|
|
106410
|
+
};
|
|
106411
|
+
}
|
|
106412
|
+
function formatContextEntry(result) {
|
|
106413
|
+
return `${JSON.stringify(result, null, 2)}
|
|
106414
|
+
`;
|
|
106415
|
+
}
|
|
106416
|
+
|
|
106417
|
+
// src/registerProjectLifecycleCommands.ts
|
|
106418
|
+
function registerProjectEntryCommand(program2) {
|
|
106419
|
+
program2.command("entry [project-dir]").description("Resolve the single Context agent entry for initialization or workflow evaluation").option("--name <name>", "display/package name override when initialization is required").option("--language <language>", "workspace and starter-template language: en | zh-CN", "en").option("--dev", "plan initialization with the locally linked @c4a/context SDK").option("--debug", "plan initialization with workspace-local tracing enabled").option("--managed", "use explicit current-conversation managed approval for workflow evaluation").addOption(new Option("--authority <authority>", "current-conversation scoped authority granted by the user; repeatable").argParser(collectWorkflowAuthorityOption).default([])).option("--format <format>", "output format: json", "json").action((projectDir, options) => {
|
|
106420
|
+
if (options.format !== "json") {
|
|
106421
|
+
throw new ContextError(ExitCode.UserError, "--format must be json", {
|
|
106422
|
+
category: ErrorCategory.UserInputInvalid
|
|
106423
|
+
});
|
|
106424
|
+
}
|
|
106425
|
+
process.stdout.write(formatContextEntry(resolveContextEntry({
|
|
106426
|
+
cwd: process.cwd(),
|
|
106427
|
+
...projectDir === undefined ? {} : { projectDir },
|
|
106428
|
+
...typeof options.name === "string" ? { name: options.name } : {},
|
|
106429
|
+
language: projectLanguage(options.language),
|
|
106430
|
+
...options.dev === true ? { dev: true } : {},
|
|
106431
|
+
...options.debug === true ? { debug: true } : {},
|
|
106432
|
+
...options.managed === true ? { managed: true } : {},
|
|
106433
|
+
authorities: workflowAuthorities(options.authority)
|
|
106434
|
+
})));
|
|
106435
|
+
});
|
|
106436
|
+
}
|
|
106261
106437
|
function registerProjectInitCommand(program2) {
|
|
106262
106438
|
program2.command("init [project-dir]").description("Initialize a project-local context workspace").option("--name <name>", "display/package name override").option("--language <language>", "workspace and starter-template language: en | zh-CN").option("--dev", "initialize with the locally linked @c4a/context SDK").option("--debug", "enable workspace-local command and Agent Graph tracing").option("--allow-nonempty", "after explicit confirmation, preserve existing files and initialize inside a non-empty non-Context directory").action(async (projectDir, options) => {
|
|
106263
106439
|
const targetRoot = resolveContextProjectInitTarget(process.cwd(), projectDir);
|
|
@@ -106385,29 +106561,29 @@ function registerProjectVerifyCommand(program2) {
|
|
|
106385
106561
|
init_cliFeedback();
|
|
106386
106562
|
init_errors();
|
|
106387
106563
|
init_exitCode();
|
|
106388
|
-
import { existsSync as
|
|
106564
|
+
import { existsSync as existsSync46 } from "node:fs";
|
|
106389
106565
|
import { cp, mkdir as mkdir32, readdir as readdir21, readFile as readFile55, rename as rename5, rm as rm19, writeFile as writeFile27 } from "node:fs/promises";
|
|
106390
106566
|
import { execFile as execFile7 } from "node:child_process";
|
|
106391
106567
|
import { homedir as homedir2 } from "node:os";
|
|
106392
|
-
import { dirname as dirname41, join as join70, resolve as
|
|
106568
|
+
import { dirname as dirname41, join as join70, resolve as resolve31 } from "node:path";
|
|
106393
106569
|
import { fileURLToPath as fileURLToPath9 } from "node:url";
|
|
106394
106570
|
import { promisify as promisify7 } from "node:util";
|
|
106395
106571
|
var execFileAsync7 = promisify7(execFile7);
|
|
106396
106572
|
var MARKETPLACE_NAME = "c4a";
|
|
106397
|
-
var PLUGIN_ID = "
|
|
106398
|
-
var PLUGIN_NAME = "
|
|
106399
|
-
var LEGACY_PLUGIN_NAMES = [];
|
|
106573
|
+
var PLUGIN_ID = "c4a@c4a";
|
|
106574
|
+
var PLUGIN_NAME = "c4a";
|
|
106575
|
+
var LEGACY_PLUGIN_NAMES = ["context"];
|
|
106400
106576
|
var ORPHAN_MARKER2 = ".orphaned_at";
|
|
106401
106577
|
var CLAUDE_PLUGIN_CACHE_ROOT_ENV2 = "C4A_CLAUDE_PLUGIN_CACHE_ROOT";
|
|
106402
106578
|
var CLAUDE_PLUGIN_CACHE_HOME_ENV2 = "C4A_CLAUDE_PLUGIN_CACHE_HOME";
|
|
106403
106579
|
var ANSI_DIM = "\x1B[2m";
|
|
106404
106580
|
var ANSI_YELLOW = "\x1B[33m";
|
|
106405
106581
|
var ANSI_RESET = "\x1B[0m";
|
|
106406
|
-
function
|
|
106582
|
+
function shellQuote10(value) {
|
|
106407
106583
|
return `'${value.replace(/'/g, "'\\''")}'`;
|
|
106408
106584
|
}
|
|
106409
106585
|
function commandLine(command2, args) {
|
|
106410
|
-
return [command2, ...args.map((arg) =>
|
|
106586
|
+
return [command2, ...args.map((arg) => shellQuote10(arg))].join(" ");
|
|
106411
106587
|
}
|
|
106412
106588
|
function dim(value) {
|
|
106413
106589
|
return `${ANSI_DIM}${value}${ANSI_RESET}`;
|
|
@@ -106442,7 +106618,7 @@ function packageCandidateDirs() {
|
|
|
106442
106618
|
function pluginRootCandidates() {
|
|
106443
106619
|
const envRoot = process.env.C4A_CONTEXT_PLUGIN_ROOT?.trim();
|
|
106444
106620
|
if (envRoot)
|
|
106445
|
-
return [
|
|
106621
|
+
return [resolve31(envRoot)];
|
|
106446
106622
|
const candidates = [];
|
|
106447
106623
|
for (const dir of packageCandidateDirs()) {
|
|
106448
106624
|
candidates.push(join70(dir, "plugins"));
|
|
@@ -106451,7 +106627,7 @@ function pluginRootCandidates() {
|
|
|
106451
106627
|
return [...new Set(candidates)];
|
|
106452
106628
|
}
|
|
106453
106629
|
function isInstallablePluginRoot(root2) {
|
|
106454
|
-
return
|
|
106630
|
+
return existsSync46(join70(root2, ".claude-plugin", "marketplace.json")) && existsSync46(join70(root2, ".agents", "plugins", "marketplace.json")) && existsSync46(join70(root2, "claude", ".claude-plugin", "plugin.json")) && existsSync46(join70(root2, "codex", ".codex-plugin", "plugin.json"));
|
|
106455
106631
|
}
|
|
106456
106632
|
function resolveBundledPluginsRoot() {
|
|
106457
106633
|
const candidates = pluginRootCandidates();
|
|
@@ -106488,13 +106664,13 @@ async function runExternalOptional(command2, args) {
|
|
|
106488
106664
|
async function commandAvailable(command2) {
|
|
106489
106665
|
return runExternalOptional("sh", ["-lc", `command -v ${command2} >/dev/null 2>&1`]);
|
|
106490
106666
|
}
|
|
106491
|
-
async function claudePluginInstalled() {
|
|
106667
|
+
async function claudePluginInstalled(pluginId) {
|
|
106492
106668
|
try {
|
|
106493
106669
|
const { stdout } = await execFileAsync7("claude", ["plugin", "list", "--json"], {
|
|
106494
106670
|
maxBuffer: 1024 * 1024
|
|
106495
106671
|
});
|
|
106496
106672
|
const parsed = JSON.parse(stdout);
|
|
106497
|
-
return Array.isArray(parsed) && parsed.some((item) => item !== null && typeof item === "object" && ("id" in item) && item.id ===
|
|
106673
|
+
return Array.isArray(parsed) && parsed.some((item) => item !== null && typeof item === "object" && ("id" in item) && item.id === pluginId);
|
|
106498
106674
|
} catch {
|
|
106499
106675
|
return false;
|
|
106500
106676
|
}
|
|
@@ -106539,7 +106715,7 @@ function isStaleMarketplaceBlock(header, block) {
|
|
|
106539
106715
|
return text5.includes('source_type = "local"') || text5.includes("/c4a-plugins") || text5.includes("context4ai/context");
|
|
106540
106716
|
}
|
|
106541
106717
|
function isStalePluginBlock(header) {
|
|
106542
|
-
return header === `plugins."context@context"` || header === "plugins.context";
|
|
106718
|
+
return header === `plugins."context@context"` || header === `plugins."context@c4a"` || header === "plugins.context";
|
|
106543
106719
|
}
|
|
106544
106720
|
function pruneLegacyCodexConfigContent(content3) {
|
|
106545
106721
|
const lines = content3.split(`
|
|
@@ -106592,7 +106768,7 @@ async function pruneLegacyCodexConfig(dryRun, steps) {
|
|
|
106592
106768
|
}
|
|
106593
106769
|
async function pruneCodexPluginCacheForName(pluginName, keepVersion, dryRun, steps) {
|
|
106594
106770
|
const cacheRoot = join70(codexHome(), "plugins", "cache", MARKETPLACE_NAME, pluginName);
|
|
106595
|
-
if (!
|
|
106771
|
+
if (!existsSync46(cacheRoot))
|
|
106596
106772
|
return;
|
|
106597
106773
|
const versions = (await readdir21(cacheRoot, { withFileTypes: true }).catch(() => [])).filter((entry) => entry.isDirectory() && entry.name !== keepVersion).map((entry) => entry.name).sort();
|
|
106598
106774
|
if (versions.length === 0)
|
|
@@ -106620,7 +106796,7 @@ async function isEmptyDir2(dir) {
|
|
|
106620
106796
|
}
|
|
106621
106797
|
async function pruneClaudeOrphanContextCache(dryRun, steps) {
|
|
106622
106798
|
const cacheRoot = claudePluginCacheRoot();
|
|
106623
|
-
if (!
|
|
106799
|
+
if (!existsSync46(cacheRoot))
|
|
106624
106800
|
return;
|
|
106625
106801
|
const removed = [];
|
|
106626
106802
|
const marketplaces = await readdir21(cacheRoot, { withFileTypes: true }).catch(() => []);
|
|
@@ -106628,14 +106804,14 @@ async function pruneClaudeOrphanContextCache(dryRun, steps) {
|
|
|
106628
106804
|
if (!marketplace.isDirectory())
|
|
106629
106805
|
continue;
|
|
106630
106806
|
const pluginDir = join70(cacheRoot, marketplace.name, PLUGIN_NAME);
|
|
106631
|
-
if (!
|
|
106807
|
+
if (!existsSync46(pluginDir))
|
|
106632
106808
|
continue;
|
|
106633
106809
|
const versions = await readdir21(pluginDir, { withFileTypes: true }).catch(() => []);
|
|
106634
106810
|
for (const version3 of versions) {
|
|
106635
106811
|
if (!version3.isDirectory())
|
|
106636
106812
|
continue;
|
|
106637
106813
|
const versionDir = join70(pluginDir, version3.name);
|
|
106638
|
-
if (!
|
|
106814
|
+
if (!existsSync46(join70(versionDir, ORPHAN_MARKER2)))
|
|
106639
106815
|
continue;
|
|
106640
106816
|
removed.push(`${marketplace.name}/${PLUGIN_NAME}/${version3.name}`);
|
|
106641
106817
|
if (!dryRun) {
|
|
@@ -106662,12 +106838,12 @@ async function pruneClaudeLegacyPluginCache(dryRun, steps) {
|
|
|
106662
106838
|
if (LEGACY_PLUGIN_NAMES.length === 0)
|
|
106663
106839
|
return;
|
|
106664
106840
|
const cacheRoot = claudePluginCacheRoot();
|
|
106665
|
-
if (!
|
|
106841
|
+
if (!existsSync46(cacheRoot))
|
|
106666
106842
|
return;
|
|
106667
106843
|
const removed = [];
|
|
106668
106844
|
for (const pluginName of LEGACY_PLUGIN_NAMES) {
|
|
106669
106845
|
const pluginDir = join70(cacheRoot, MARKETPLACE_NAME, pluginName);
|
|
106670
|
-
if (!
|
|
106846
|
+
if (!existsSync46(pluginDir))
|
|
106671
106847
|
continue;
|
|
106672
106848
|
removed.push(`${MARKETPLACE_NAME}/${pluginName}`);
|
|
106673
106849
|
if (!dryRun) {
|
|
@@ -106794,7 +106970,7 @@ async function materializeCodexPluginCache(root2, version3, dryRun, steps) {
|
|
|
106794
106970
|
const target = codexPluginCacheDir(version3);
|
|
106795
106971
|
steps.push({
|
|
106796
106972
|
agent: "codex",
|
|
106797
|
-
command: `materialize Codex plugin cache: ${
|
|
106973
|
+
command: `materialize Codex plugin cache: ${shellQuote10(source2)} -> ${shellQuote10(target)}`,
|
|
106798
106974
|
status: dryRun ? "planned" : "ran"
|
|
106799
106975
|
});
|
|
106800
106976
|
if (dryRun)
|
|
@@ -106804,7 +106980,7 @@ async function materializeCodexPluginCache(root2, version3, dryRun, steps) {
|
|
|
106804
106980
|
const previous3 = `${target}.previous-${process.pid}-${Date.now()}`;
|
|
106805
106981
|
await rm19(temporary, { recursive: true, force: true });
|
|
106806
106982
|
await cp(source2, temporary, { recursive: true, force: true });
|
|
106807
|
-
const hadPrevious =
|
|
106983
|
+
const hadPrevious = existsSync46(target);
|
|
106808
106984
|
try {
|
|
106809
106985
|
if (hadPrevious)
|
|
106810
106986
|
await rename5(target, previous3);
|
|
@@ -106813,7 +106989,7 @@ async function materializeCodexPluginCache(root2, version3, dryRun, steps) {
|
|
|
106813
106989
|
await rm19(previous3, { recursive: true, force: true });
|
|
106814
106990
|
} catch (error) {
|
|
106815
106991
|
await rm19(temporary, { recursive: true, force: true });
|
|
106816
|
-
if (hadPrevious && !
|
|
106992
|
+
if (hadPrevious && !existsSync46(target) && existsSync46(previous3))
|
|
106817
106993
|
await rename5(previous3, target);
|
|
106818
106994
|
throw error;
|
|
106819
106995
|
}
|
|
@@ -106825,6 +107001,13 @@ async function installClaude(root2, dryRun, steps) {
|
|
|
106825
107001
|
const installArgs = ["plugin", "install", PLUGIN_ID, "--scope", "user"];
|
|
106826
107002
|
steps.push({ agent: "claude", command: commandLine("claude", addArgs), status: dryRun ? "planned" : "ran" });
|
|
106827
107003
|
if (dryRun) {
|
|
107004
|
+
for (const pluginName of LEGACY_PLUGIN_NAMES) {
|
|
107005
|
+
steps.push({
|
|
107006
|
+
agent: "claude",
|
|
107007
|
+
command: commandLine("claude", ["plugin", "uninstall", `${pluginName}@${MARKETPLACE_NAME}`, "--scope", "user"]),
|
|
107008
|
+
status: "planned"
|
|
107009
|
+
});
|
|
107010
|
+
}
|
|
106828
107011
|
steps.push({ agent: "claude", command: commandLine("claude", installArgs), status: "planned" });
|
|
106829
107012
|
return;
|
|
106830
107013
|
}
|
|
@@ -106832,7 +107015,15 @@ async function installClaude(root2, dryRun, steps) {
|
|
|
106832
107015
|
if (!added) {
|
|
106833
107016
|
await runExternal("claude", ["plugin", "marketplace", "update", MARKETPLACE_NAME]);
|
|
106834
107017
|
}
|
|
106835
|
-
|
|
107018
|
+
for (const pluginName of LEGACY_PLUGIN_NAMES) {
|
|
107019
|
+
const legacyPluginId = `${pluginName}@${MARKETPLACE_NAME}`;
|
|
107020
|
+
if (!await claudePluginInstalled(legacyPluginId))
|
|
107021
|
+
continue;
|
|
107022
|
+
const uninstallArgs = ["plugin", "uninstall", legacyPluginId, "--scope", "user"];
|
|
107023
|
+
steps.push({ agent: "claude", command: commandLine("claude", uninstallArgs), status: "ran" });
|
|
107024
|
+
await runExternal("claude", uninstallArgs);
|
|
107025
|
+
}
|
|
107026
|
+
if (await claudePluginInstalled(PLUGIN_ID)) {
|
|
106836
107027
|
const uninstallArgs = ["plugin", "uninstall", PLUGIN_ID, "--scope", "user"];
|
|
106837
107028
|
steps.push({ agent: "claude", command: commandLine("claude", uninstallArgs), status: "ran" });
|
|
106838
107029
|
await runExternal("claude", uninstallArgs);
|
|
@@ -106848,12 +107039,12 @@ async function installCodex(root2, dryRun, steps) {
|
|
|
106848
107039
|
steps.push({ agent: "codex", command: commandLine("codex", addArgs), status: dryRun ? "planned" : "ran" });
|
|
106849
107040
|
steps.push({
|
|
106850
107041
|
agent: "codex",
|
|
106851
|
-
command: `ensure ${
|
|
107042
|
+
command: `ensure ${shellQuote10(join70(codexHome(), "config.toml"))} registers local marketplace ${shellQuote10(MARKETPLACE_NAME)}`,
|
|
106852
107043
|
status: dryRun ? "planned" : "ran"
|
|
106853
107044
|
});
|
|
106854
107045
|
steps.push({
|
|
106855
107046
|
agent: "codex",
|
|
106856
|
-
command: `ensure ${
|
|
107047
|
+
command: `ensure ${shellQuote10(join70(codexHome(), "config.toml"))} enables ${shellQuote10(PLUGIN_ID)}`,
|
|
106857
107048
|
status: dryRun ? "planned" : "ran"
|
|
106858
107049
|
});
|
|
106859
107050
|
if (dryRun) {
|
|
@@ -107034,6 +107225,7 @@ function registerPackageCommands(program2) {
|
|
|
107034
107225
|
|
|
107035
107226
|
// src/cli.ts
|
|
107036
107227
|
var TOP_LEVEL_COMMANDS = new Set([
|
|
107228
|
+
"entry",
|
|
107037
107229
|
"init",
|
|
107038
107230
|
"plugin",
|
|
107039
107231
|
"status",
|
|
@@ -107072,7 +107264,7 @@ function readPackageVersion() {
|
|
|
107072
107264
|
let dir = dirname42(fileURLToPath10(import.meta.url));
|
|
107073
107265
|
for (let i2 = 0;i2 < 8; i2++) {
|
|
107074
107266
|
const pkg = join71(dir, "package.json");
|
|
107075
|
-
if (
|
|
107267
|
+
if (existsSync47(pkg)) {
|
|
107076
107268
|
const parsed = JSON.parse(readFileSync10(pkg, "utf8"));
|
|
107077
107269
|
return parsed.version ?? "unknown";
|
|
107078
107270
|
}
|
|
@@ -107089,10 +107281,10 @@ function readQuickstartPath() {
|
|
|
107089
107281
|
let dir = dirname42(fileURLToPath10(import.meta.url));
|
|
107090
107282
|
for (let i2 = 0;i2 < 8; i2++) {
|
|
107091
107283
|
const candidate = join71(dir, "docs", "quickstart.md");
|
|
107092
|
-
if (
|
|
107284
|
+
if (existsSync47(candidate))
|
|
107093
107285
|
return candidate;
|
|
107094
107286
|
const pkg = join71(dir, "package.json");
|
|
107095
|
-
if (
|
|
107287
|
+
if (existsSync47(pkg))
|
|
107096
107288
|
return candidate;
|
|
107097
107289
|
const parent = dirname42(dir);
|
|
107098
107290
|
if (parent === dir)
|
|
@@ -107185,6 +107377,7 @@ function createCliProgram() {
|
|
|
107185
107377
|
});
|
|
107186
107378
|
const baseHelpInformation = program2.helpInformation.bind(program2);
|
|
107187
107379
|
program2.helpInformation = () => `${headerHelpText()}${baseHelpInformation()}${quickstartHelpText()}`;
|
|
107380
|
+
registerProjectEntryCommand(program2);
|
|
107188
107381
|
registerProjectInitCommand(program2);
|
|
107189
107382
|
registerPluginCommands(program2);
|
|
107190
107383
|
registerDebugCommands(program2);
|