@c4a/context-cli 0.5.29-alpha.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.
- package/README.md +122 -0
- package/cli.js +37711 -0
- package/package.json +18 -0
- package/plugin/.claude-plugin/plugin.json +16 -0
- package/plugin/.claude-plugin/plugin.json.template +16 -0
- package/plugin/.codex-plugin/plugin.json +35 -0
- package/plugin/.codex-plugin/plugin.json.template +35 -0
- package/plugin/commands/align.md +54 -0
- package/plugin/commands/capture-aspect.md +17 -0
- package/plugin/commands/capture-code.md +25 -0
- package/plugin/commands/capture.md +67 -0
- package/plugin/commands/compile.md +89 -0
- package/plugin/commands/context.md +30 -0
- package/plugin/commands/drop.md +17 -0
- package/plugin/commands/extract.md +18 -0
- package/plugin/commands/init.md +95 -0
- package/plugin/commands/purge.md +18 -0
- package/plugin/commands/query.md +13 -0
- package/plugin/commands/status.md +21 -0
- package/plugin/skills/align-finalize/SKILL.md +137 -0
- package/plugin/skills/align-propose/SKILL.md +142 -0
- package/plugin/skills/align-scan/SKILL.md +161 -0
- package/plugin/skills/align-scan/references/data-model.md +343 -0
- package/plugin/skills/align-scan/references/user-question-contract.md +155 -0
- package/plugin/skills/compile-close/SKILL.md +122 -0
- package/plugin/skills/compile-draft/SKILL.md +246 -0
- package/plugin/skills/context-query/SKILL.md +166 -0
- package/plugin/skills/drop/SKILL.md +163 -0
- package/plugin/skills/semantic-reconcile/SKILL.md +106 -0
- package/scripts/build-plugin.ts +70 -0
- package/scripts/postinstall.mjs +183 -0
- package/templates/aspects/code/prompt.md +29 -0
- package/templates/aspects/design-system/prompt.md +27 -0
- package/templates/aspects/graphql/prompt.md +24 -0
- package/templates/aspects/openapi/prompt.md +24 -0
- package/wasm/tree-sitter-tsx.wasm +0 -0
- package/wasm/tree-sitter-typescript.wasm +0 -0
- package/wasm/tree-sitter.wasm +0 -0
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: semantic-reconcile
|
|
3
|
+
description: >
|
|
4
|
+
Internal skill for `/context:compile` and `/context:drop`. Consumes only
|
|
5
|
+
`context reconcile prepare` output, judges semantic relation/action for each
|
|
6
|
+
item, and emits a schema_version 1.0 semantic decision document for
|
|
7
|
+
`context reconcile review` / `context reconcile apply`.
|
|
8
|
+
tools:
|
|
9
|
+
- Bash
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# semantic-reconcile — decide Section reconciliation
|
|
13
|
+
|
|
14
|
+
Judge duplicate, merge, conflict, reanchor, and unsupported cases from the
|
|
15
|
+
CLI-prepared context. Emit decisions only; the CLI performs every write.
|
|
16
|
+
|
|
17
|
+
## TL;DR — Non-negotiables
|
|
18
|
+
|
|
19
|
+
- Input is only the `context reconcile prepare` payload. Do not Read, Glob, Grep, or Write workspace `raw/`, `knowledge/`, `archive/`, or `decisions/`.
|
|
20
|
+
- Output exactly one YAML or JSON document with `schema_version: "1.0"` and `decisions[]`.
|
|
21
|
+
- Use canonical relations: `exact_duplicate`, `strong_equivalent`, `near_duplicate`, `complement`, `supersedes`, `conflicts`, `reanchor`, `unsupported`, `keep_separate`, `ask_user`.
|
|
22
|
+
- Use canonical actions: `duplicate_skip`, `merge_update`, `supersede`, `reanchor`, `remove_unsupported`, `keep_separate`, `split_then_reanchor`, `ask_user`.
|
|
23
|
+
- `no-op` is not a decision action. For unchanged refresh items, emit no decision or `duplicate_skip`.
|
|
24
|
+
- Never expose `src-N`, Section ids, or source refs as the user-facing choice. They may appear only in the structured payload.
|
|
25
|
+
- `merge_update` is legal only when the final Section content is supported by one valid `source_ref`; otherwise use `keep_separate`, `split_then_reanchor`, or `ask_user`.
|
|
26
|
+
- Unresolved conflicts and low-confidence support questions must be `action: ask_user`.
|
|
27
|
+
|
|
28
|
+
<reference>
|
|
29
|
+
|
|
30
|
+
## Decision Shape
|
|
31
|
+
|
|
32
|
+
```yaml
|
|
33
|
+
schema_version: "1.0"
|
|
34
|
+
decisions:
|
|
35
|
+
- item_id: claim-001
|
|
36
|
+
relation: near_duplicate
|
|
37
|
+
action: merge_update
|
|
38
|
+
target:
|
|
39
|
+
node: payment-runtime
|
|
40
|
+
section_id: section-3
|
|
41
|
+
proposed:
|
|
42
|
+
content: "Runtime isolation uses sandboxing to avoid state pollution."
|
|
43
|
+
confidence: confirmed
|
|
44
|
+
source_ref: "src-2#runtime L12-14"
|
|
45
|
+
source_ref_text: "sandboxing to avoid state pollution"
|
|
46
|
+
rationale: "The new evidence refines the same claim."
|
|
47
|
+
user_confirmation:
|
|
48
|
+
required: true
|
|
49
|
+
question_type: merge_confirmation
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Action Rules
|
|
53
|
+
|
|
54
|
+
| action | Required fields |
|
|
55
|
+
|---|---|
|
|
56
|
+
| `duplicate_skip` | `target` |
|
|
57
|
+
| `merge_update` | `target`, `proposed.content`, `proposed.source_ref` |
|
|
58
|
+
| `supersede` | `target`, `proposed.kind`, `proposed.content`, `proposed.source_ref` |
|
|
59
|
+
| `reanchor` | `target`, `proposed.source_ref`, `proposed.confidence` |
|
|
60
|
+
| `remove_unsupported` | `target` |
|
|
61
|
+
| `keep_separate` | `target`, `proposed.kind`, `proposed.content`, `proposed.source_ref` |
|
|
62
|
+
| `split_then_reanchor` | `target`, `proposed.sections[]` |
|
|
63
|
+
| `ask_user` | `user_confirmation.required: true` |
|
|
64
|
+
|
|
65
|
+
</reference>
|
|
66
|
+
|
|
67
|
+
<procedures>
|
|
68
|
+
|
|
69
|
+
### Step 1 — Read Prepared Context
|
|
70
|
+
|
|
71
|
+
Use the caller-provided `context reconcile prepare` output. For each item,
|
|
72
|
+
compare `proposed`, `candidates`, `previous_decisions`, and `evidence`.
|
|
73
|
+
|
|
74
|
+
### Step 2 — Reuse Stable Priors
|
|
75
|
+
|
|
76
|
+
If `previous_decisions[]` shows the same boundary and the prepared item still
|
|
77
|
+
matches, emit the same final action. If the target changed, treat the previous
|
|
78
|
+
decision as a prior only and continue judging.
|
|
79
|
+
|
|
80
|
+
### Step 3 — Decide Relation And Action
|
|
81
|
+
|
|
82
|
+
Classify each item:
|
|
83
|
+
|
|
84
|
+
- Exact same claim already active -> `exact_duplicate` + `duplicate_skip`.
|
|
85
|
+
- Same claim with safer wording and one supporting source -> `strong_equivalent` or `near_duplicate` + `merge_update`.
|
|
86
|
+
- Additional but separate boundary -> `complement` + `keep_separate`.
|
|
87
|
+
- New material replaces old rule -> `supersedes` + `supersede`.
|
|
88
|
+
- Direct contradiction -> `conflicts` + `ask_user`.
|
|
89
|
+
- Drop item still fully supported elsewhere -> `reanchor` + `reanchor`.
|
|
90
|
+
- Drop item partly supported -> `reanchor` + `split_then_reanchor`.
|
|
91
|
+
- No surviving support -> `unsupported` + `remove_unsupported`.
|
|
92
|
+
- Evidence is close but not enough -> `ask_user`.
|
|
93
|
+
|
|
94
|
+
### Step 4 — Emit Decisions
|
|
95
|
+
|
|
96
|
+
Emit only executable final decisions plus unresolved `ask_user` questions.
|
|
97
|
+
Do not include prose outside the document.
|
|
98
|
+
|
|
99
|
+
### Step 5 — Self-verify
|
|
100
|
+
|
|
101
|
+
- [ ] Every decision uses canonical relation/action values. If not, **Step 3**.
|
|
102
|
+
- [ ] No `no-op` action appears. If not, **Step 3**.
|
|
103
|
+
- [ ] Every write action has the required fields from [Action Rules](#action-rules). If not, **Step 4**.
|
|
104
|
+
- [ ] No workspace files were read or written directly. If violated, restart from **Step 1**.
|
|
105
|
+
|
|
106
|
+
</procedures>
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
/**
|
|
3
|
+
* build-plugin.ts — materialize plugin manifests from templates by
|
|
4
|
+
* substituting `__VERSION__` with the value from package.json.
|
|
5
|
+
*
|
|
6
|
+
* Template sources:
|
|
7
|
+
* - plugin/.claude-plugin/plugin.json.template
|
|
8
|
+
* - plugin/.codex-plugin/plugin.json.template
|
|
9
|
+
*
|
|
10
|
+
* Outputs:
|
|
11
|
+
* - plugin/.claude-plugin/plugin.json
|
|
12
|
+
* - plugin/.codex-plugin/plugin.json
|
|
13
|
+
*
|
|
14
|
+
* Run after `bun run build` (or as part of it) so packaged tarballs ship
|
|
15
|
+
* version-correct plugin manifests. Idempotent — overwrites on every run.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
import { readFile, writeFile } from "node:fs/promises";
|
|
19
|
+
import { dirname, resolve } from "node:path";
|
|
20
|
+
import { fileURLToPath } from "node:url";
|
|
21
|
+
|
|
22
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
23
|
+
const pkgRoot = resolve(__dirname, "..");
|
|
24
|
+
|
|
25
|
+
async function main(): Promise<void> {
|
|
26
|
+
const pkgRaw = await readFile(resolve(pkgRoot, "package.json"), "utf-8");
|
|
27
|
+
const pkg = JSON.parse(pkgRaw) as { version?: string };
|
|
28
|
+
const version = pkg.version;
|
|
29
|
+
if (!version) {
|
|
30
|
+
throw new Error("package.json is missing `version`");
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const manifests = [
|
|
34
|
+
{
|
|
35
|
+
label: "claude",
|
|
36
|
+
templatePath: resolve(pkgRoot, "plugin/.claude-plugin/plugin.json.template"),
|
|
37
|
+
outputPath: resolve(pkgRoot, "plugin/.claude-plugin/plugin.json"),
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
label: "codex",
|
|
41
|
+
templatePath: resolve(pkgRoot, "plugin/.codex-plugin/plugin.json.template"),
|
|
42
|
+
outputPath: resolve(pkgRoot, "plugin/.codex-plugin/plugin.json"),
|
|
43
|
+
},
|
|
44
|
+
] as const;
|
|
45
|
+
|
|
46
|
+
for (const manifest of manifests) {
|
|
47
|
+
const template = await readFile(manifest.templatePath, "utf-8");
|
|
48
|
+
const rendered = template.replace(/__VERSION__/g, version);
|
|
49
|
+
|
|
50
|
+
await writeFile(manifest.outputPath, rendered);
|
|
51
|
+
|
|
52
|
+
const parsed = JSON.parse(rendered) as { name?: string; version?: string; skills?: string };
|
|
53
|
+
if (parsed.name !== "context") {
|
|
54
|
+
throw new Error(`${manifest.label} plugin.json name must be "context", got "${parsed.name}"`);
|
|
55
|
+
}
|
|
56
|
+
if (parsed.version !== version) {
|
|
57
|
+
throw new Error(`${manifest.label} plugin.json version mismatch: ${parsed.version} vs ${version}`);
|
|
58
|
+
}
|
|
59
|
+
if (manifest.label === "codex" && parsed.skills !== "./skills/") {
|
|
60
|
+
throw new Error(`codex plugin.json must point skills to "./skills/", got "${parsed.skills}"`);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
process.stdout.write(`${manifest.label} plugin.json generated (name=${parsed.name}, version=${parsed.version})\n`);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
main().catch((err) => {
|
|
68
|
+
process.stderr.write(`build-plugin failed: ${err instanceof Error ? err.message : String(err)}\n`);
|
|
69
|
+
process.exit(1);
|
|
70
|
+
});
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* postinstall hook for @c4a/context-cli.
|
|
4
|
+
*
|
|
5
|
+
* The goal is narrow: when someone installs this package as a Claude Code
|
|
6
|
+
* plugin, the `context` bin should end up on PATH so `/context:*` slash
|
|
7
|
+
* commands can Bash out to it. In every other install scenario (library
|
|
8
|
+
* dependency, `bun install -g`, CI, local `bun link`) we do nothing.
|
|
9
|
+
*
|
|
10
|
+
* Dangerous things this script used to do (review findings 高-1 / 高-2):
|
|
11
|
+
* - Recursion: the child `bun install -g @c4a/context-cli` inherits the
|
|
12
|
+
* same Claude env vars that triggered us, runs postinstall again, and
|
|
13
|
+
* loops. Fixed by (a) hard re-entry guard via CONTEXT_CLI_POSTINSTALL
|
|
14
|
+
* in the child env, and (b) skipping entirely when we are already
|
|
15
|
+
* inside a global install (`npm_config_global === "true"`).
|
|
16
|
+
* - Dev mode break: pinning the registry spec `@c4a/context-cli@<version>`
|
|
17
|
+
* ignores the actual install source (local tarball, file:, github:,
|
|
18
|
+
* unpublished pre-release). Fixed by never spawning a child install;
|
|
19
|
+
* we print a single actionable hint with the registry fallback command.
|
|
20
|
+
* The plugin tarball already contains the whole CLI, so the user can
|
|
21
|
+
* just `bun install -g <same source>` themselves — we can't guess the
|
|
22
|
+
* source reliably from inside postinstall.
|
|
23
|
+
*
|
|
24
|
+
* Structure: all decision logic lives in the pure, exported `decide()`
|
|
25
|
+
* function. The top-level side-effect wrapper is the only thing that reads
|
|
26
|
+
* `process.env`, spawns the PATH probe, or writes to stderr. This split
|
|
27
|
+
* lets a sibling `.test.ts` exercise every branch without spawning
|
|
28
|
+
* subprocesses (Bun test's subprocess sandboxing has been unreliable in
|
|
29
|
+
* this package, so in-process tests are the practical way to cover the
|
|
30
|
+
* script).
|
|
31
|
+
*/
|
|
32
|
+
|
|
33
|
+
import { spawnSync } from "node:child_process";
|
|
34
|
+
import { realpathSync } from "node:fs";
|
|
35
|
+
import process from "node:process";
|
|
36
|
+
import { pathToFileURL } from "node:url";
|
|
37
|
+
|
|
38
|
+
export const RE_ENTRY_ENV = "CONTEXT_CLI_POSTINSTALL";
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Pure decision function. Given an env snapshot and a "does `context` bin
|
|
42
|
+
* exist on PATH?" predicate result, return either a hint to print or a
|
|
43
|
+
* "do nothing" sentinel.
|
|
44
|
+
*
|
|
45
|
+
* Shape:
|
|
46
|
+
* { action: "skip", reason: "<why>" }
|
|
47
|
+
* | { action: "hint", lines: string[] }
|
|
48
|
+
*
|
|
49
|
+
* Every branch that reads process state in the real run is modeled here so
|
|
50
|
+
* tests can pass synthetic envs. The caller decides whether to actually
|
|
51
|
+
* print or set the re-entry guard.
|
|
52
|
+
*/
|
|
53
|
+
export function decide(env, hasContextBin) {
|
|
54
|
+
if (env[RE_ENTRY_ENV] === "1") {
|
|
55
|
+
return { action: "skip", reason: "re-entry guard" };
|
|
56
|
+
}
|
|
57
|
+
if (env.CI === "true" || env.CI === "1") {
|
|
58
|
+
return { action: "skip", reason: "CI" };
|
|
59
|
+
}
|
|
60
|
+
if (env.npm_config_global === "true") {
|
|
61
|
+
return { action: "skip", reason: "already global install" };
|
|
62
|
+
}
|
|
63
|
+
if (env.CONTEXT_CLI_SKIP_AUTO_LINK === "1") {
|
|
64
|
+
return { action: "skip", reason: "explicit opt-out" };
|
|
65
|
+
}
|
|
66
|
+
if (!looksLikeClaudePluginInstall(env)) {
|
|
67
|
+
return { action: "skip", reason: "not a Claude plugin install" };
|
|
68
|
+
}
|
|
69
|
+
if (hasContextBin) {
|
|
70
|
+
return { action: "skip", reason: "context already on PATH" };
|
|
71
|
+
}
|
|
72
|
+
const version = env.npm_package_version ?? "latest";
|
|
73
|
+
return {
|
|
74
|
+
action: "hint",
|
|
75
|
+
lines: [
|
|
76
|
+
"Claude plugin installed. To enable `/context:*` slash commands, make " +
|
|
77
|
+
"the `context` bin available on PATH by running one of:",
|
|
78
|
+
` bun install -g @c4a/context-cli@${version} # install from npm registry`,
|
|
79
|
+
" bun link # if installing a local build",
|
|
80
|
+
],
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Heuristic: does the caller's env smell like a Claude plugin install?
|
|
86
|
+
* We require the env var's *value* to contain "claude" (case-insensitive),
|
|
87
|
+
* not just the var to be set — `npm_config_user_agent` is set by every
|
|
88
|
+
* install, and `CLAUDE_PLUGIN_INSTALL=0` should not trigger us either.
|
|
89
|
+
*/
|
|
90
|
+
export function looksLikeClaudePluginInstall(env) {
|
|
91
|
+
const hints = ["CLAUDE_PLUGIN_INSTALL", "CLAUDE_CODE_PLUGIN", "npm_config_user_agent"];
|
|
92
|
+
for (const key of hints) {
|
|
93
|
+
const value = env[key];
|
|
94
|
+
if (!value) continue;
|
|
95
|
+
if (value.toLowerCase().includes("claude")) return true;
|
|
96
|
+
}
|
|
97
|
+
return false;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Real-world `hasContextBin` probe: shell out to `command -v` / `where`.
|
|
102
|
+
* Kept separate from `decide()` so tests can inject a synthetic value.
|
|
103
|
+
*/
|
|
104
|
+
export function probeContextBin() {
|
|
105
|
+
const lookup = process.platform === "win32"
|
|
106
|
+
? spawnSync("where", ["context"], { stdio: "ignore" })
|
|
107
|
+
: spawnSync("sh", ["-c", "command -v context"], { stdio: "ignore" });
|
|
108
|
+
return lookup.status === 0;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
function log(msg) {
|
|
112
|
+
process.stderr.write(`[context-cli postinstall] ${msg}\n`);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
function main() {
|
|
116
|
+
const env = process.env;
|
|
117
|
+
// First pass with hasContextBin=false tells us whether every *other* gate
|
|
118
|
+
// was passed. Only if the decision is "hint" do we need the real PATH
|
|
119
|
+
// probe (avoids shelling out to sh/where in the common skip cases).
|
|
120
|
+
const provisional = decide(env, false);
|
|
121
|
+
if (provisional.action === "skip") return;
|
|
122
|
+
|
|
123
|
+
// Decision said "hint" — now probe the real PATH. If context IS on PATH,
|
|
124
|
+
// the user doesn't need the hint.
|
|
125
|
+
const final = decide(env, probeContextBin());
|
|
126
|
+
if (final.action === "hint") {
|
|
127
|
+
for (const line of final.lines) log(line);
|
|
128
|
+
}
|
|
129
|
+
// Set the re-entry guard so any child process we may spawn in the future
|
|
130
|
+
// (we currently don't, but belt-and-suspenders against recursion) will
|
|
131
|
+
// inherit it and skip their own postinstall.
|
|
132
|
+
env[RE_ENTRY_ENV] = "1";
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// Side-effect wrapper only runs when this file is executed directly as a
|
|
136
|
+
// script (the postinstall lifecycle does that). When the file is imported
|
|
137
|
+
// by a test, `main()` is not invoked.
|
|
138
|
+
//
|
|
139
|
+
// IMPORTANT — two quirks that the obvious
|
|
140
|
+
// `import.meta.url === \`file://${process.argv[1]}\``
|
|
141
|
+
// check silently fails on, producing an invisible-no-op postinstall:
|
|
142
|
+
//
|
|
143
|
+
// 1. **Percent-encoding**: `import.meta.url` is always WHATWG-encoded
|
|
144
|
+
// (`%20` for spaces, %-hex for many punctuation chars, uppercase
|
|
145
|
+
// Windows drive letters, UNC `\\?\` prefixes). Raw `argv[1]` isn't.
|
|
146
|
+
// A package install under `/Users/Dev Tools/...` reproducibly no-ops
|
|
147
|
+
// with the interpolated check; going through `pathToFileURL` fixes
|
|
148
|
+
// it.
|
|
149
|
+
// 2. **Symlink resolution**: on macOS `/tmp` is a symlink to
|
|
150
|
+
// `/private/tmp`, and `import.meta.url` resolves that; `argv[1]`
|
|
151
|
+
// does not. npm stashes packages under symlinked paths on some
|
|
152
|
+
// setups (npm's cache, nvm prefixes, corporate homedir mounts). We
|
|
153
|
+
// realpath `argv[1]` before URL-encoding so both sides compare the
|
|
154
|
+
// canonical target.
|
|
155
|
+
//
|
|
156
|
+
// Either quirk alone turns the postinstall script into a silent no-op —
|
|
157
|
+
// exactly the invisible-failure mode npm postinstall scripts are
|
|
158
|
+
// infamous for. The combined check below is validated by the subprocess
|
|
159
|
+
// tests in postinstall.test.ts.
|
|
160
|
+
export function isDirectRun(metaUrl, argv1) {
|
|
161
|
+
if (!argv1) return false;
|
|
162
|
+
try {
|
|
163
|
+
let resolved = argv1;
|
|
164
|
+
try {
|
|
165
|
+
resolved = realpathSync(argv1);
|
|
166
|
+
} catch {
|
|
167
|
+
// argv[1] may not exist yet (weird, but possible under npm install
|
|
168
|
+
// lifecycle timing). Fall back to the raw path — pathToFileURL
|
|
169
|
+
// still normalizes encoding, so spaces-but-no-symlinks still works.
|
|
170
|
+
}
|
|
171
|
+
return metaUrl === pathToFileURL(resolved).href;
|
|
172
|
+
} catch {
|
|
173
|
+
return false;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
if (isDirectRun(import.meta.url, process.argv[1])) {
|
|
178
|
+
try {
|
|
179
|
+
main();
|
|
180
|
+
} catch (err) {
|
|
181
|
+
log(`postinstall error: ${err instanceof Error ? err.message : String(err)}`);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# aspect: code
|
|
2
|
+
|
|
3
|
+
> Code structure aspect. The `context capture-code` command invokes the
|
|
4
|
+
> `@c4a/extract` / `@c4a/extract-ts` pipeline directly — it does not read
|
|
5
|
+
> this file. The prompt exists as a placeholder so the init flow is
|
|
6
|
+
> uniform and so a future scripted-aspect mechanism can take over without
|
|
7
|
+
> reshuffling directory structure.
|
|
8
|
+
|
|
9
|
+
## Target
|
|
10
|
+
|
|
11
|
+
Extract `Package` / `Symbol` nodes and `imports` / `calls` / `extends` edges
|
|
12
|
+
from the current git worktree.
|
|
13
|
+
|
|
14
|
+
## Schema
|
|
15
|
+
|
|
16
|
+
Payloads are written by the CLI as JSONL files under each dated bucket:
|
|
17
|
+
|
|
18
|
+
- `packages.jsonl` — one `Package` per line
|
|
19
|
+
- `symbols.jsonl` — one `Symbol` per line (recursive `members` flattened)
|
|
20
|
+
- `edges.jsonl` — one relation per line (optional)
|
|
21
|
+
- `_meta.yaml` — bucket metadata (`commit`, `captured_at`, `script_hash`,
|
|
22
|
+
`content_hash`)
|
|
23
|
+
|
|
24
|
+
## Notes
|
|
25
|
+
|
|
26
|
+
- Currently driven by the CLI, not by a per-aspect script. The scripted
|
|
27
|
+
`capture.ts` contract for non-code aspects is planned for a later release.
|
|
28
|
+
- source-id is always `aspect:code`.
|
|
29
|
+
- Bucket name is `YYYY-MM-DD-<sha7>` where `<sha7>` is `git rev-parse --short HEAD`.
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# aspect: design-system
|
|
2
|
+
|
|
3
|
+
> Design-system aspect placeholder. The current CLI does not yet provide
|
|
4
|
+
> a scripted capture driver for this aspect — `context capture-aspect
|
|
5
|
+
> design-system` will report that scripted aspects beyond `code` are not
|
|
6
|
+
> implemented. This file exists so the init flow keeps the aspect slot
|
|
7
|
+
> consistent for a future scripted-capture release.
|
|
8
|
+
|
|
9
|
+
## Target
|
|
10
|
+
|
|
11
|
+
Extract design tokens (color / spacing / typography) and component usage
|
|
12
|
+
patterns from the codebase and design docs.
|
|
13
|
+
|
|
14
|
+
## Schema (planned contract)
|
|
15
|
+
|
|
16
|
+
When scripted capture lands, payloads will be written into dated buckets
|
|
17
|
+
under `raw/aspect/design-system/<YYYY-MM-DD>-<hash7>/`:
|
|
18
|
+
|
|
19
|
+
- `facts.jsonl` — one design-system fact per line (token definitions, usage
|
|
20
|
+
rules, deprecations)
|
|
21
|
+
- `_meta.yaml` — bucket metadata (`token_count`, `source_files`,
|
|
22
|
+
`captured_at`, `script_hash`, `content_hash`)
|
|
23
|
+
|
|
24
|
+
## Notes
|
|
25
|
+
|
|
26
|
+
- Not executable by the current CLI.
|
|
27
|
+
- source-id reserved as `aspect:design-system`.
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# aspect: graphql
|
|
2
|
+
|
|
3
|
+
> GraphQL aspect placeholder. The current CLI does not yet provide a
|
|
4
|
+
> scripted capture driver — `context capture-aspect graphql` will report
|
|
5
|
+
> that scripted aspects beyond `code` are not implemented.
|
|
6
|
+
|
|
7
|
+
## Target
|
|
8
|
+
|
|
9
|
+
Extract GraphQL type definitions, resolver mappings, and usage patterns
|
|
10
|
+
from schema files and server code.
|
|
11
|
+
|
|
12
|
+
## Schema (planned contract)
|
|
13
|
+
|
|
14
|
+
Payloads produced by the future scripted capture:
|
|
15
|
+
|
|
16
|
+
- `facts.jsonl` — GraphQL facts (type definitions, field descriptions,
|
|
17
|
+
resolver docs, deprecations)
|
|
18
|
+
- `_meta.yaml` — bucket metadata (`schema_file`, `type_count`,
|
|
19
|
+
`captured_at`, `script_hash`, `content_hash`)
|
|
20
|
+
|
|
21
|
+
## Notes
|
|
22
|
+
|
|
23
|
+
- Not executable by the current CLI.
|
|
24
|
+
- source-id reserved as `aspect:graphql`.
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# aspect: openapi
|
|
2
|
+
|
|
3
|
+
> OpenAPI aspect placeholder. The current CLI does not yet provide a
|
|
4
|
+
> scripted capture driver — `context capture-aspect openapi` will report
|
|
5
|
+
> that scripted aspects beyond `code` are not implemented.
|
|
6
|
+
|
|
7
|
+
## Target
|
|
8
|
+
|
|
9
|
+
Extract HTTP endpoints, request/response schemas, and auth requirements
|
|
10
|
+
from OpenAPI spec files in the repo.
|
|
11
|
+
|
|
12
|
+
## Schema (planned contract)
|
|
13
|
+
|
|
14
|
+
Payloads produced by the future scripted capture will land under dated
|
|
15
|
+
buckets and contain:
|
|
16
|
+
|
|
17
|
+
- `facts.jsonl` — endpoint-level facts (path, method, auth, deprecation)
|
|
18
|
+
- `_meta.yaml` — bucket metadata (`spec_version`, `endpoint_count`,
|
|
19
|
+
`captured_at`, `script_hash`, `content_hash`)
|
|
20
|
+
|
|
21
|
+
## Notes
|
|
22
|
+
|
|
23
|
+
- Not executable by the current CLI.
|
|
24
|
+
- source-id reserved as `aspect:openapi`.
|
|
Binary file
|
|
Binary file
|
|
Binary file
|