project-tiny-context-harness 0.2.60 → 0.2.61

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.
@@ -21,33 +21,38 @@ The output answers:
21
21
  For this exact plan, what must be true before a future executor can honestly say the task is complete?
22
22
  ```
23
23
 
24
- This Skill is generic. Do not embed business-specific rules, provider-specific rules, product-domain assumptions, artifact schemas, API names, UI names, status names, or one-off project logic in this Skill. If the user's plan contains a specific domain, derive acceptance items from that plan and the project Context during the current invocation only.
24
+ This Skill is generic. Do not embed business-specific rules, vendor-specific rules, product-domain assumptions, artifact schemas, concrete interface names, UI names, state names, or one-off project logic in this Skill. If the user's plan contains a specific domain, derive acceptance items from that plan and the project Context during the current invocation only.
25
25
 
26
26
  ## Required Outputs
27
27
 
28
- Every completed invocation must produce:
29
-
30
- 1. A preserved copy of the plan under `tmp/ty-context/plan-acceptance/`.
31
- 2. A rigorous acceptance checklist derived from the plan and relevant project Context.
32
- 3. A goal/target-mode prompt the user can paste directly into Codex.
28
+ Every completed invocation must produce:
29
+
30
+ 1. A preserved copy of the plan under `tmp/ty-context/plan-acceptance/`. The copied plan is the implementation/source plan, not acceptance proof.
31
+ 2. A rigorous full acceptance checklist derived from the plan and relevant project Context. The full checklist is the complete acceptance standard.
32
+ 3. A goal/target-mode prompt the user can paste directly into Codex. The prompt may include a compact checklist summary for direction, priority and recovery navigation, but the full checklist owns the acceptance details.
33
+ 4. When a local audit path is referenced, it is temporary execution/progress state only, not Context and not proof by itself.
33
34
 
34
35
  Exception: if the Context confirmation gate below triggers, stop after materializing the plan and reading enough Context to explain the uncertainty. Ask the user for confirmation before producing the checklist or goal/target-mode prompt.
35
36
 
36
- The goal/target-mode prompt must be no longer than 3980 characters, including line breaks. This conservative budget keeps the prompt below Codex's 4000-character practical paste boundary even when character counting differs slightly. Keep the prompt information-dense: preserve required paths, core acceptance criteria, evidence rules, blockers and false-completion traps while using compact wording. Use the user's language when practical. For Chinese requests, use this shape:
37
-
38
- ```text
39
- 实施计划: tmp/ty-context/plan-acceptance/<plan>.md
40
- 可多开agent,agent名额不够了就关掉不用的。
41
- <验收清单>
42
- ```
43
-
44
- For English requests, use this shape:
45
-
46
- ```text
47
- Plan: tmp/ty-context/plan-acceptance/<plan>.md
48
- You may use multiple agents; if agent slots run low, close idle or unnecessary agents.
49
- <acceptance checklist>
50
- ```
37
+ The goal/target-mode prompt must be no longer than 3850 characters, including line breaks. This conservative budget keeps the prompt below Codex's 4000-character practical paste boundary even when character counting differs slightly. Keep the prompt information-dense: preserve required paths, core acceptance criteria, evidence rules, blockers and false-completion traps while using compact wording. Use the user's language when practical. For Chinese requests, use this shape:
38
+
39
+ ```text
40
+ 实施计划: tmp/ty-context/plan-acceptance/<plan>.md(source/implementation plan,非验收证明)
41
+ 可多开agent,agent名额不够了就关掉不用的。
42
+ 完整验收清单: tmp/ty-context/plan-acceptance/<plan>-acceptance-checklist.md(该文件是完整验收标准,验收以这个为准。完成前必须逐项检查,不满足则继续实现。)
43
+ 执行审计: tmp/ty-context/plan-acceptance/<plan>-local-audit.md(临时 progress state,非 Context/proof)
44
+ <验收清单>
45
+ ```
46
+
47
+ For English requests, use this shape:
48
+
49
+ ```text
50
+ Plan: tmp/ty-context/plan-acceptance/<plan>.md (implementation/source plan, not acceptance proof)
51
+ You may use multiple agents; if agent slots run low, close idle or unnecessary agents.
52
+ Full checklist: tmp/ty-context/plan-acceptance/<plan>-acceptance-checklist.md (complete acceptance standard; acceptance is judged against it; every item must be checked before completion)
53
+ Local audit: tmp/ty-context/plan-acceptance/<plan>-local-audit.md (temporary execution/progress state, not Context or proof)
54
+ <acceptance checklist>
55
+ ```
51
56
 
52
57
  This resource lifecycle line is part of the generated execution prompt. It authorizes parallel decomposition for the future executor while requiring unused agents to be closed when slots run low.
53
58
 
@@ -121,8 +126,8 @@ Rules:
121
126
  - If the user pasted the plan text, write the pasted plan exactly into `tmp/ty-context/plan-acceptance/<safe-plan-name>.md`.
122
127
  - Preserve the plan content. Do not summarize, normalize, reorder, translate, or edit it while materializing it.
123
128
  - Use a stable readable filename derived from the plan title, source filename, or user topic. Use lowercase letters, digits, hyphens, and `.md`.
124
- - If the source plan cannot be found or read, stop and report the missing source. Do not invent a plan.
125
- - The materialized plan is temporary execution input. It is not durable Context and not proof that any acceptance item passed.
129
+ - If the source plan cannot be found or read, stop and report the missing source. Do not invent a plan.
130
+ - The materialized plan is temporary implementation/source input. It is not durable Context, not acceptance proof and not proof that any acceptance item passed.
126
131
 
127
132
  Recommended paths:
128
133
 
@@ -187,9 +192,12 @@ Before the detailed checklist, write a compact contract:
187
192
  - Completion definition: <what must be true>
188
193
  - Core surfaces: <code/API/UI/data/runtime/artifact/test/context/etc.>
189
194
  - Explicit non-goals: <items>
190
- - External blockers: <accounts/session/credentials/network/cloud/manual approval/etc.>
191
- - Evidence standard: <accepted proof types>
192
- ```
195
+ - External blockers: <accounts/session/credentials/network/cloud/manual approval/etc.>
196
+ - Evidence standard: <accepted proof types>
197
+ - Current-state claims: <which "current", "generated", "synced", "tested", "accepted" or runtime claims require current evidence>
198
+ - Evidence ledger required: <whether the checklist or future executor must maintain current evidence by item>
199
+ - Invalid completion evidence: <stale artifacts, code-only edits, partial tests, unexercised runtime, mismatched read paths or other evidence that cannot prove completion>
200
+ ```
193
201
 
194
202
  If the plan uses broad words such as `all`, `complete`, `maximum`, `maximized`, `accepted`, `formal`, `production`, `real`, `current`, or `verified`, convert them into explicit inventory and evidence requirements.
195
203
 
@@ -214,9 +222,28 @@ Column rules:
214
222
  - `Verification method`: concrete command, check, inspection path, API call, UI check, artifact validation, or manual proof.
215
223
  - `Fail / not accepted if`: concrete invalidation case.
216
224
 
217
- Each item must be evidence-bound and falsifiable. Split combined requirements into separate rows.
218
-
219
- ## Hard Blocker Handling
225
+ Each item must be evidence-bound and falsifiable. Split combined requirements into separate rows.
226
+
227
+ For current-state or evidence-heavy plans, also require the future executor to maintain an Evidence Ledger table:
228
+
229
+ ```markdown
230
+ | AC | Expected state | Current observed state | Current evidence | Evidence location / API / UI / command | Conclusion | Gap / blocker |
231
+ |---|---|---|---|---|---|---|
232
+ ```
233
+
234
+ Allowed `Conclusion` values:
235
+
236
+ - `proven`
237
+ - `unproven`
238
+ - `stale-evidence`
239
+ - `runtime-disconnected`
240
+ - `implementation-drift`
241
+ - `blocked`
242
+ - `deferred-by-explicit-scope`
243
+
244
+ Missing ledger evidence means incomplete, not complete. Do not let missing evidence, old evidence, partial evidence or evidence from a different read path satisfy a current-state claim.
245
+
246
+ ## Hard Blocker Handling
220
247
 
221
248
  Treat any unresolved required blocker as non-completion. A checklist may describe blocked acceptance work, but blocked work is still not accepted until the required evidence exists.
222
249
 
@@ -258,7 +285,7 @@ When user input is still required, the blocker request must be the smallest conc
258
285
  - Acceptance impact if the blocker remains unresolved.
259
286
  - Allowed fallback, deferred or narrowed-scope option, if the plan or Context permits one.
260
287
 
261
- Do not replace this with broad requests such as "provide the token", "send the AppSecret" or "give me the configuration credentials" when a narrower page, field, runtime setup step or delegated user action would satisfy the blocker.
288
+ Do not replace this with broad requests such as "provide the token", "send the secret value" or "give me the configuration credentials" when a narrower page, field, runtime setup step or delegated user action would satisfy the blocker.
262
289
 
263
290
  ## Generic Acceptance Dimensions
264
291
 
@@ -342,18 +369,28 @@ After the checklist, include traps that a future executor must not mistake for c
342
369
 
343
370
  Use generic wording. Do not add business-specific traps to the Skill itself.
344
371
 
345
- Template:
346
-
347
- ```markdown
348
- ## False-Completion Traps
349
-
350
- - <activity> is not enough unless <acceptance proof> also exists.
351
- - <partial proof> cannot prove <full acceptance item>.
352
- - <old/stale/mismatched evidence> cannot prove current completion.
353
- - <surface A> passing does not prove <surface B> unless the checklist links them.
354
- ```
355
-
356
- ## Suggested Execution Order
372
+ Template:
373
+
374
+ ```markdown
375
+ ## False-Completion Traps
376
+
377
+ - <activity> is not enough unless <acceptance proof> also exists.
378
+ - <partial proof> cannot prove <full acceptance item>.
379
+ - <old/stale/mismatched evidence> cannot prove current completion.
380
+ - <surface A> passing does not prove <surface B> unless the checklist links them.
381
+ ```
382
+
383
+ For evidence-ledger plans, keep the traps generic and cover these cases when relevant:
384
+
385
+ - Code-only changes without current execution or acceptance evidence.
386
+ - UI/API shell behavior without the backing data, runtime or artifact evidence required by the checklist.
387
+ - Stale artifacts or stale runtime evidence.
388
+ - Evidence from a mismatched read path, service path, artifact path or runtime instance.
389
+ - Unexercised runtime or unexercised fallback behavior.
390
+ - Partial tests, smoke-only checks or dry runs when the plan requires broader current proof.
391
+ - API/UI/data/test contradictions that remain unresolved.
392
+
393
+ ## Suggested Execution Order
357
394
 
358
395
  Suggest an execution order that prioritizes the highest-risk proof first:
359
396
 
@@ -389,14 +426,16 @@ Every generated checklist must pass this self-test:
389
426
 
390
427
  After compiling the checklist, produce a paste-ready goal/target-mode prompt.
391
428
 
392
- Hard requirements:
393
-
394
- - The prompt must be no longer than 3980 characters including line breaks. Treat 3980 as the effective hard budget and preserve information density; do not drop required paths, core acceptance categories, blocker rules, evidence rules or false-completion traps merely to be short.
395
- - The first line must identify the plan path.
396
- - Use `实施计划: <path>` for Chinese prompts and `Plan: <path>` for English prompts.
397
- - The second line must be a resource lifecycle instruction: `可多开agent,agent名额不够了就关掉不用的。` for Chinese prompts or `You may use multiple agents; if agent slots run low, close idle or unnecessary agents.` for English prompts.
398
- - The remaining content must be the acceptance checklist or a compact version of it.
429
+ Hard requirements:
430
+
431
+ - The prompt must be no longer than 3850 characters including line breaks. Treat 3850 as the effective hard budget and preserve information density; do not drop required paths, core acceptance categories, blocker rules, evidence rules or false-completion traps merely to be short.
432
+ - The first line must identify the plan path.
433
+ - Use `实施计划: <path>` for Chinese prompts and `Plan: <path>` for English prompts. The line must say the plan is the implementation/source plan and not acceptance proof.
434
+ - The second line must be a resource lifecycle instruction: `可多开agent,agent名额不够了就关掉不用的。` for Chinese prompts or `You may use multiple agents; if agent slots run low, close idle or unnecessary agents.` for English prompts.
435
+ - The remaining content must be the acceptance checklist or a compact version of it.
399
436
  - The prompt must be self-contained enough for goal/target-mode execution.
437
+ - The prompt must identify the full checklist path and say it is the complete acceptance standard. Chinese prompts must include this exact sentence: `该文件是完整验收标准,验收以这个为准。完成前必须逐项检查,不满足则继续实现。` English prompts must say the full checklist is the complete acceptance standard, acceptance is judged against it, and every item must be checked before completion.
438
+ - If the prompt uses a compact checklist summary, say the full checklist owns details and acceptance authority; the compact summary owns direction, priority and recovery navigation; overlap is allowed; conflicts are resolved in favor of the full checklist.
400
439
  - The prompt must identify a local audit path, normally `tmp/ty-context/plan-acceptance/<plan-slug>-local-audit.md`, and require the future executor to read it before resuming, keep it current during execution, and use it only as target-mode acceptance progress state.
401
440
  - The prompt must require the local audit to record overall status (`complete`, `incomplete`, `blocked` or `narrowed-scope-complete`), each core AC status and current evidence, commands with result/time/failure reason, artifact or evidence paths, blockers and missing evidence, acceptance impact, explicit deferred or narrowed scope, and stale/partial/smoke/dry-run/research evidence that cannot prove full completion.
402
441
  - The prompt must say that local audit is not Context, not product-quality proof, not a global task manager, and not a replacement for project tests, CI, review, human acceptance, Task Contract or workflow-contract `plan.md`.
@@ -405,15 +444,16 @@ Hard requirements:
405
444
  - Do not include Markdown tables inside the prompt if they make it too long.
406
445
  - Prefer short numbered items over verbose prose.
407
446
  - If the full checklist is too large, write the full checklist to `tmp/ty-context/plan-acceptance/<plan-slug>-acceptance-checklist.md`, then compress the goal/target-mode prompt by increasing information density while preserving all core acceptance categories.
408
- - The compact prompt may reference the full checklist path, but it must still include the core completion criteria directly.
447
+ - The compact prompt may reference the full checklist path, but it must still include the core completion criteria directly and state that the summary is direction/priority/recovery navigation, not the acceptance authority.
409
448
 
410
449
  Recommended compact Chinese prompt shape:
411
450
 
412
451
  ```text
413
- 实施计划: tmp/ty-context/plan-acceptance/<plan-slug>.md
452
+ 实施计划: tmp/ty-context/plan-acceptance/<plan-slug>.md(source/implementation plan,非验收证明)
414
453
  可多开agent,agent名额不够了就关掉不用的。
415
- 完整验收清单: tmp/ty-context/plan-acceptance/<plan-slug>-acceptance-checklist.md
416
- 执行审计: tmp/ty-context/plan-acceptance/<plan-slug>-local-audit.md
454
+ 完整验收清单: tmp/ty-context/plan-acceptance/<plan-slug>-acceptance-checklist.md(该文件是完整验收标准,验收以这个为准。完成前必须逐项检查,不满足则继续实现。)
455
+ 执行审计: tmp/ty-context/plan-acceptance/<plan-slug>-local-audit.md(临时 progress state,非 Context/proof)
456
+ 本摘要只负责 direction/priority/recovery navigation;允许与完整 checklist 重叠,冲突时以完整 checklist 为准。
417
457
 
418
458
  验收清单:
419
459
  AC1 <核心完成定义,包含验收证据>
@@ -437,10 +477,11 @@ AC14 完成前审计:逐条对照实施计划和完整 checklist;每个 core
437
477
  Recommended compact English prompt shape:
438
478
 
439
479
  ```text
440
- Plan: tmp/ty-context/plan-acceptance/<plan-slug>.md
480
+ Plan: tmp/ty-context/plan-acceptance/<plan-slug>.md (implementation/source plan, not acceptance proof)
441
481
  You may use multiple agents; if agent slots run low, close idle or unnecessary agents.
442
- Full checklist: tmp/ty-context/plan-acceptance/<plan-slug>-acceptance-checklist.md
443
- Local audit: tmp/ty-context/plan-acceptance/<plan-slug>-local-audit.md
482
+ Full checklist: tmp/ty-context/plan-acceptance/<plan-slug>-acceptance-checklist.md (complete acceptance standard; acceptance is judged against it; every item must be checked before completion)
483
+ Local audit: tmp/ty-context/plan-acceptance/<plan-slug>-local-audit.md (temporary progress state, not Context or proof)
484
+ This summary is only direction, priority and recovery navigation; overlap with the full checklist is allowed, and the full checklist wins conflicts.
444
485
 
445
486
  Acceptance checklist:
446
487
  AC1 <core completion definition with required evidence>
@@ -460,8 +501,8 @@ AC14 Final audit: compare every item against the plan and full checklist; every
460
501
 
461
502
  Do not count these as completion: code-only changes, plan-only updates, partial tests, stale or partial evidence, infrastructure without acceptance proof, runtime not configured/exercised, artifact not accepted by validator, API/UI not reflecting accepted evidence, unexercised fallback, unresolved hard blockers, or contradictions between API/UI/data/tests.
462
503
  ```
463
-
464
- Before final response, check the prompt length. If it exceeds 3980 characters, compress by tightening wording and referring to the full checklist path while preserving required paths, core AC categories, blocker/evidence rules and false-completion traps; then check again.
504
+
505
+ Before final response, check the prompt length. If it exceeds 3850 characters, compress by tightening wording and referring to the full checklist path while preserving required paths, core AC categories, blocker/evidence rules and false-completion traps; then check again.
465
506
 
466
507
  ## Final Response Requirements
467
508
 
@@ -0,0 +1,21 @@
1
+ import type { SourcePackMode } from "../lib/source-pack-types.js";
2
+ export interface ExportContextArgs {
3
+ full: boolean;
4
+ code: boolean;
5
+ all: boolean;
6
+ sourceMode?: SourcePackMode;
7
+ taskName?: string;
8
+ check: boolean;
9
+ output?: string;
10
+ profile?: string;
11
+ includeContext: string[];
12
+ includeCode: string[];
13
+ bundleStrategy?: "auto" | "area" | "topdir" | "config";
14
+ maxPackFiles?: number;
15
+ maxBundleCharacters?: number;
16
+ redactionStrict: boolean;
17
+ prune?: number;
18
+ help: boolean;
19
+ }
20
+ export declare function parseArgs(args: string[]): ExportContextArgs;
21
+ export declare function helpText(): string;
@@ -0,0 +1,149 @@
1
+ export function parseArgs(args) {
2
+ const parsed = {
3
+ full: false,
4
+ code: false,
5
+ all: false,
6
+ check: false,
7
+ includeContext: [],
8
+ includeCode: [],
9
+ redactionStrict: false,
10
+ help: false
11
+ };
12
+ for (let index = 0; index < args.length; index += 1) {
13
+ const arg = args[index];
14
+ if (arg === "--full")
15
+ parsed.full = true;
16
+ else if (arg === "--code")
17
+ parsed.code = true;
18
+ else if (arg === "--all")
19
+ parsed.all = true;
20
+ else if (arg === "--code-index")
21
+ parsed.sourceMode = "code-index";
22
+ else if (arg === "--source-pack")
23
+ parsed.sourceMode = "source-pack";
24
+ else if (arg === "--code-bundles")
25
+ parsed.sourceMode = "code-bundles";
26
+ else if (arg === "--check")
27
+ parsed.check = true;
28
+ else if (arg === "--help" || arg === "-h")
29
+ parsed.help = true;
30
+ else if (arg === "--redaction-strict")
31
+ parsed.redactionStrict = true;
32
+ else if (arg === "--task-context")
33
+ index = readValue(args, index, "export-context --task-context requires a name", (value) => {
34
+ parsed.sourceMode = "task-context";
35
+ parsed.taskName = value;
36
+ });
37
+ else if (arg.startsWith("--task-context=")) {
38
+ parsed.sourceMode = "task-context";
39
+ parsed.taskName = inlineValue(arg, "--task-context", "export-context --task-context requires a name");
40
+ }
41
+ else if (arg === "--output")
42
+ index = readValue(args, index, "export-context --output requires a path", (value) => (parsed.output = value));
43
+ else if (arg.startsWith("--output="))
44
+ parsed.output = inlineValue(arg, "--output", "export-context --output requires a path");
45
+ else if (arg === "--profile")
46
+ index = readValue(args, index, "export-context --profile requires an id", (value) => (parsed.profile = value));
47
+ else if (arg.startsWith("--profile="))
48
+ parsed.profile = inlineValue(arg, "--profile", "export-context --profile requires an id");
49
+ else if (arg === "--include-context")
50
+ index = readValue(args, index, "export-context --include-context requires a repo-relative path or glob", (value) => parsed.includeContext.push(value));
51
+ else if (arg.startsWith("--include-context="))
52
+ parsed.includeContext.push(inlineValue(arg, "--include-context", "export-context --include-context requires a repo-relative path or glob"));
53
+ else if (arg === "--include-code")
54
+ index = readValue(args, index, "export-context --include-code requires a repo-relative path or glob", (value) => parsed.includeCode.push(value));
55
+ else if (arg.startsWith("--include-code="))
56
+ parsed.includeCode.push(inlineValue(arg, "--include-code", "export-context --include-code requires a repo-relative path or glob"));
57
+ else if (arg === "--bundle-strategy")
58
+ index = readValue(args, index, "export-context --bundle-strategy requires auto, area, topdir or config", (value) => (parsed.bundleStrategy = parseBundleStrategy(value)));
59
+ else if (arg.startsWith("--bundle-strategy="))
60
+ parsed.bundleStrategy = parseBundleStrategy(inlineValue(arg, "--bundle-strategy", "export-context --bundle-strategy requires auto, area, topdir or config"));
61
+ else if (arg === "--max-pack-files")
62
+ index = readValue(args, index, "export-context --max-pack-files requires a positive integer", (value) => (parsed.maxPackFiles = parseInteger(value, "--max-pack-files", false)));
63
+ else if (arg.startsWith("--max-pack-files="))
64
+ parsed.maxPackFiles = parseInteger(inlineValue(arg, "--max-pack-files", "export-context --max-pack-files requires a positive integer"), "--max-pack-files", false);
65
+ else if (arg === "--max-bundle-characters")
66
+ index = readValue(args, index, "export-context --max-bundle-characters requires a positive integer", (value) => (parsed.maxBundleCharacters = parseInteger(value, "--max-bundle-characters", false)));
67
+ else if (arg.startsWith("--max-bundle-characters="))
68
+ parsed.maxBundleCharacters = parseInteger(inlineValue(arg, "--max-bundle-characters", "export-context --max-bundle-characters requires a positive integer"), "--max-bundle-characters", false);
69
+ else if (arg === "--prune")
70
+ index = readValue(args, index, "export-context --prune requires a non-negative integer", (value) => (parsed.prune = parseInteger(value, "--prune", true)));
71
+ else if (arg.startsWith("--prune="))
72
+ parsed.prune = parseInteger(inlineValue(arg, "--prune", "export-context --prune requires a non-negative integer"), "--prune", true);
73
+ else
74
+ throw new Error(`unknown export-context argument: ${arg}`);
75
+ }
76
+ validateParsedArgs(parsed);
77
+ return parsed;
78
+ }
79
+ export function helpText() {
80
+ return `ty-context export-context:
81
+ export-context --full [--output tmp/ty-context/context-exports/<name>.md] [--check]
82
+ export-context --code [--output tmp/ty-context/context-exports/<name>.md] [--check]
83
+ export-context --all [--check]
84
+ export-context --code-index [--profile <id>] [--include-code <path-or-glob>] [--check]
85
+ export-context --source-pack [--profile <id>] [--bundle-strategy auto|area|topdir|config] [--max-pack-files 5] [--max-bundle-characters <n>] [--redaction-strict] [--prune <count>] [--check]
86
+ export-context --code-bundles [--profile <id>] [--include-code <path-or-glob>] [--max-pack-files 5] [--check]
87
+ export-context --task-context <name> [--profile <id>] [--include-context <path-or-glob>] [--include-code <path-or-glob>] [--max-pack-files 5] [--redaction-strict] [--check]
88
+
89
+ Creates temporary Markdown artifacts for copying or external-tool ingestion.
90
+ --full exports the project Context summary as a full-project-context artifact.
91
+ --code exports one current implementation snapshot as a code-level-implementation artifact.
92
+ --all exports both default artifacts in one command.
93
+ Source Pack modes write timestamped directories plus latest/ under tmp/ty-context/context-exports/**.
94
+ --source-pack and --task-context are bounded to at most 5 files; --max-pack-files cannot exceed 5.
95
+ Profiles are export selectors read from <harnessRoot>/config.yaml; verification entries are listed, not executed.
96
+ Secret redaction is always enabled; --redaction-strict fails if redaction was required.
97
+ The artifact must stay under tmp/ty-context/context-exports/** and must not be referenced from project_context/context.toml.`;
98
+ }
99
+ function validateParsedArgs(parsed) {
100
+ const modeCount = Number(parsed.full) + Number(parsed.code) + Number(parsed.all) + Number(parsed.sourceMode !== undefined);
101
+ if (modeCount > 1) {
102
+ throw new Error("export-context accepts exactly one mode: --full, --code, --all, --code-index, --source-pack, --code-bundles or --task-context");
103
+ }
104
+ if (parsed.all && parsed.output) {
105
+ throw new Error("export-context --all writes two default artifacts; --output is only supported with --full or --code");
106
+ }
107
+ if (parsed.sourceMode && parsed.output) {
108
+ throw new Error("export-context --output is only supported with legacy --full or --code single-artifact modes");
109
+ }
110
+ if (!parsed.sourceMode && hasSourcePackOnlyOptions(parsed)) {
111
+ throw new Error("profile/include/bundle/max/prune/redaction-strict options are only supported with Source Pack modes");
112
+ }
113
+ }
114
+ function readValue(args, index, message, apply) {
115
+ const value = args[index + 1];
116
+ if (!value || value.startsWith("--")) {
117
+ throw new Error(message);
118
+ }
119
+ apply(value);
120
+ return index + 1;
121
+ }
122
+ function inlineValue(arg, flag, message) {
123
+ const value = arg.slice(`${flag}=`.length).trim();
124
+ if (!value)
125
+ throw new Error(message);
126
+ return value;
127
+ }
128
+ function parseBundleStrategy(value) {
129
+ if (value === "auto" || value === "area" || value === "topdir" || value === "config")
130
+ return value;
131
+ throw new Error("export-context --bundle-strategy must be one of auto, area, topdir or config");
132
+ }
133
+ function parseInteger(value, flag, allowZero) {
134
+ const parsed = Number.parseInt(value, 10);
135
+ if (!Number.isInteger(parsed) || String(parsed) !== value.trim() || parsed < 0 || (!allowZero && parsed === 0)) {
136
+ throw new Error(`export-context ${flag} requires ${allowZero ? "a non-negative" : "a positive"} integer`);
137
+ }
138
+ return parsed;
139
+ }
140
+ function hasSourcePackOnlyOptions(parsed) {
141
+ return Boolean(parsed.profile ||
142
+ parsed.includeContext.length > 0 ||
143
+ parsed.includeCode.length > 0 ||
144
+ parsed.bundleStrategy ||
145
+ parsed.maxPackFiles ||
146
+ parsed.maxBundleCharacters ||
147
+ parsed.redactionStrict ||
148
+ parsed.prune !== undefined);
149
+ }
@@ -1,4 +1,6 @@
1
+ import { parseArgs, helpText } from "./export-context-args.js";
1
2
  import { runExportContext } from "../lib/context-export.js";
3
+ import { runSourcePackExport } from "../lib/source-pack-export.js";
2
4
  export async function exportContext(args) {
3
5
  let parsed;
4
6
  try {
@@ -9,7 +11,7 @@ export async function exportContext(args) {
9
11
  process.exitCode = 1;
10
12
  return;
11
13
  }
12
- if (parsed.help || (!parsed.full && !parsed.code && !parsed.all)) {
14
+ if (parsed.help || (!parsed.full && !parsed.code && !parsed.all && !parsed.sourceMode)) {
13
15
  console.log(helpText());
14
16
  if (!parsed.help) {
15
17
  process.exitCode = 1;
@@ -17,32 +19,25 @@ export async function exportContext(args) {
17
19
  return;
18
20
  }
19
21
  try {
20
- if (parsed.all) {
21
- const now = new Date();
22
- const fullReport = await runExportContext(process.cwd(), {
23
- full: true,
24
- check: parsed.check,
25
- now
26
- });
27
- const codeReport = await runExportContext(process.cwd(), {
28
- code: true,
22
+ if (parsed.sourceMode) {
23
+ printSourcePackReport(await runSourcePackExport(process.cwd(), {
24
+ mode: parsed.sourceMode,
29
25
  check: parsed.check,
30
- now
31
- });
32
- console.log(parsed.check ? "export-context check OK" : "export-context wrote artifacts");
33
- console.log("mode: all");
34
- console.log("outputs:");
35
- console.log(`- full: ${fullReport.outputRelativePath}`);
36
- console.log(`- code: ${codeReport.outputRelativePath}`);
37
- console.log(`source context count: ${fullReport.sourceContextCount}`);
38
- console.log(`source code count: ${codeReport.sourceCodeCount ?? codeReport.sourceFiles.length}`);
39
- console.log(`total code lines: ${codeReport.totalLines ?? 0}`);
40
- console.log(`total code characters: ${codeReport.totalCharacters ?? 0}`);
41
- console.log("warnings:");
42
- printWarnings([
43
- ...fullReport.warnings.map((warning) => `full: ${warning}`),
44
- ...codeReport.warnings.map((warning) => `code: ${warning}`)
45
- ]);
26
+ command: `ty-context export-context ${args.join(" ")}`.trim(),
27
+ profile: parsed.profile,
28
+ includeContext: parsed.includeContext,
29
+ includeCode: parsed.includeCode,
30
+ bundleStrategy: parsed.bundleStrategy,
31
+ maxPackFiles: parsed.maxPackFiles,
32
+ maxBundleCharacters: parsed.maxBundleCharacters,
33
+ redactionStrict: parsed.redactionStrict,
34
+ prune: parsed.prune,
35
+ taskName: parsed.taskName
36
+ }), parsed.check);
37
+ return;
38
+ }
39
+ if (parsed.all) {
40
+ await runLegacyAll(parsed.check);
46
41
  return;
47
42
  }
48
43
  const report = await runExportContext(process.cwd(), {
@@ -74,57 +69,42 @@ export async function exportContext(args) {
74
69
  process.exitCode = 1;
75
70
  }
76
71
  }
77
- function parseArgs(args) {
78
- const parsed = { full: false, code: false, all: false, check: false, help: false };
79
- for (let index = 0; index < args.length; index += 1) {
80
- const arg = args[index];
81
- if (arg === "--full") {
82
- parsed.full = true;
83
- continue;
84
- }
85
- if (arg === "--code") {
86
- parsed.code = true;
87
- continue;
88
- }
89
- if (arg === "--all") {
90
- parsed.all = true;
91
- continue;
92
- }
93
- if (arg === "--check") {
94
- parsed.check = true;
95
- continue;
96
- }
97
- if (arg === "--help" || arg === "-h") {
98
- parsed.help = true;
99
- continue;
100
- }
101
- if (arg === "--output") {
102
- const value = args[index + 1];
103
- if (!value || value.startsWith("--")) {
104
- throw new Error("export-context --output requires a path");
105
- }
106
- parsed.output = value;
107
- index += 1;
108
- continue;
109
- }
110
- if (arg.startsWith("--output=")) {
111
- const value = arg.slice("--output=".length).trim();
112
- if (!value) {
113
- throw new Error("export-context --output requires a path");
114
- }
115
- parsed.output = value;
116
- continue;
117
- }
118
- throw new Error(`unknown export-context argument: ${arg}`);
119
- }
120
- const modeCount = Number(parsed.full) + Number(parsed.code) + Number(parsed.all);
121
- if (modeCount > 1) {
122
- throw new Error("export-context accepts exactly one of --full, --code or --all");
72
+ async function runLegacyAll(check) {
73
+ const now = new Date();
74
+ const fullReport = await runExportContext(process.cwd(), { full: true, check, now });
75
+ const codeReport = await runExportContext(process.cwd(), { code: true, check, now });
76
+ console.log(check ? "export-context check OK" : "export-context wrote artifacts");
77
+ console.log("mode: all");
78
+ console.log("outputs:");
79
+ console.log(`- full: ${fullReport.outputRelativePath}`);
80
+ console.log(`- code: ${codeReport.outputRelativePath}`);
81
+ console.log(`source context count: ${fullReport.sourceContextCount}`);
82
+ console.log(`source code count: ${codeReport.sourceCodeCount ?? codeReport.sourceFiles.length}`);
83
+ console.log(`total code lines: ${codeReport.totalLines ?? 0}`);
84
+ console.log(`total code characters: ${codeReport.totalCharacters ?? 0}`);
85
+ console.log("warnings:");
86
+ printWarnings([
87
+ ...fullReport.warnings.map((warning) => `full: ${warning}`),
88
+ ...codeReport.warnings.map((warning) => `code: ${warning}`)
89
+ ]);
90
+ }
91
+ function printSourcePackReport(report, check) {
92
+ console.log(check ? "export-context check OK" : "export-context wrote artifacts");
93
+ console.log(`mode: ${report.mode}`);
94
+ console.log(`output directory: ${report.outputRelativePath}`);
95
+ console.log(`source code count: ${report.sourceCodeCount}`);
96
+ console.log(`total lines: ${report.totalLines}`);
97
+ console.log(`total characters: ${report.totalCharacters}`);
98
+ console.log("artifacts:");
99
+ for (const artifact of report.artifacts) {
100
+ console.log(`- ${artifact.kind}: ${artifact.path} (${artifact.characters} chars, ${artifact.source_count} sources)`);
123
101
  }
124
- if (parsed.all && parsed.output) {
125
- throw new Error("export-context --all writes two default artifacts; --output is only supported with --full or --code");
102
+ console.log("recommended upload sets:");
103
+ for (const [name, files] of Object.entries(report.recommendedUploadSets)) {
104
+ console.log(`- ${name}: ${files.join(", ")}`);
126
105
  }
127
- return parsed;
106
+ console.log("warnings:");
107
+ printWarnings(report.warnings);
128
108
  }
129
109
  function printWarnings(warnings) {
130
110
  if (warnings.length === 0) {
@@ -135,15 +115,3 @@ function printWarnings(warnings) {
135
115
  console.log(`- ${warning}`);
136
116
  }
137
117
  }
138
- function helpText() {
139
- return `ty-context export-context:
140
- export-context --full [--output tmp/ty-context/context-exports/<name>.md] [--check]
141
- export-context --code [--output tmp/ty-context/context-exports/<name>.md] [--check]
142
- export-context --all [--check]
143
-
144
- Creates temporary Markdown artifacts for copying or external-tool ingestion.
145
- --full exports the project Context summary as a full-project-context artifact.
146
- --code exports one current implementation snapshot as a code-level-implementation artifact.
147
- --all exports both default artifacts in one command.
148
- The artifact must stay under tmp/ty-context/context-exports/** and must not be referenced from project_context/context.toml.`;
149
- }
@@ -30,8 +30,8 @@ export function help() {
30
30
  doctor Diagnose project configuration and drift
31
31
  check-modularity --touched|--file <path>|--base <ref> [--limit 300] [--fail-on-warning]
32
32
  Warn when selected handwritten source files exceed a line-count limit
33
- export-context --full|--code|--all [--output <path>] [--check]
34
- Export a temporary Context summary or code implementation Markdown artifact
33
+ export-context --full|--code|--all|--source-pack|--code-index|--task-context
34
+ Export temporary Context, code snapshot or bounded Source Pack artifacts
35
35
  validate <gate> Run a Harness validation gate
36
36
  validate-context Validate Minimal Context fact-source recoverability
37
37
  validate-code-modularity
@@ -0,0 +1,10 @@
1
+ import type { ContextAreaMapping } from "./source-pack-types.js";
2
+ export interface CodeClassification {
3
+ language: string;
4
+ summary: string;
5
+ tags: string[];
6
+ routes: string[];
7
+ score: number;
8
+ bucket: string;
9
+ }
10
+ export declare function classifyCodeFile(relative: string, content: string, areas: ContextAreaMapping[]): CodeClassification;