project-tiny-context-harness 0.2.81 → 0.2.83

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.
Files changed (52) hide show
  1. package/README.md +11 -3
  2. package/assets/README.md +11 -3
  3. package/assets/README.zh-CN.md +9 -1
  4. package/assets/protected-harness-baseline.json +18 -0
  5. package/assets/skills/composite-long-task-workflow/SKILL.md +21 -1
  6. package/assets/skills/composite-long-task-workflow/assets/execution-binding.template.md +10 -0
  7. package/assets/skills/composite-long-task-workflow/assets/goal-objective.template.md +6 -15
  8. package/assets/skills/composite-long-task-workflow/references/composite-long-task-workflow-protocol.md +32 -15
  9. package/dist/commands/composite-long-task.js +45 -2
  10. package/dist/lib/superpowers-task-ac010.d.ts +6 -0
  11. package/dist/lib/superpowers-task-ac010.js +26 -0
  12. package/dist/lib/superpowers-task-assertion-normalizers.js +8 -1
  13. package/dist/lib/superpowers-task-assertions.js +35 -20
  14. package/dist/lib/superpowers-task-attempt.d.ts +4 -0
  15. package/dist/lib/superpowers-task-attempt.js +102 -0
  16. package/dist/lib/superpowers-task-command-specs.d.ts +3 -0
  17. package/dist/lib/superpowers-task-command-specs.js +52 -0
  18. package/dist/lib/superpowers-task-compile.d.ts +4 -1
  19. package/dist/lib/superpowers-task-compile.js +7 -1
  20. package/dist/lib/superpowers-task-contradictions.d.ts +6 -0
  21. package/dist/lib/superpowers-task-contradictions.js +126 -0
  22. package/dist/lib/superpowers-task-current-evidence.d.ts +3 -0
  23. package/dist/lib/superpowers-task-current-evidence.js +154 -0
  24. package/dist/lib/superpowers-task-delivery.js +30 -18
  25. package/dist/lib/superpowers-task-derive.d.ts +1 -0
  26. package/dist/lib/superpowers-task-derive.js +76 -1
  27. package/dist/lib/superpowers-task-evidence-kernel.d.ts +12 -0
  28. package/dist/lib/superpowers-task-evidence-kernel.js +351 -0
  29. package/dist/lib/superpowers-task-evidence-records.d.ts +2 -0
  30. package/dist/lib/superpowers-task-evidence-records.js +55 -0
  31. package/dist/lib/superpowers-task-evidence.d.ts +10 -0
  32. package/dist/lib/superpowers-task-evidence.js +141 -0
  33. package/dist/lib/superpowers-task-fields.d.ts +22 -0
  34. package/dist/lib/superpowers-task-fields.js +276 -0
  35. package/dist/lib/superpowers-task-gates.js +36 -24
  36. package/dist/lib/superpowers-task-harness-drift.d.ts +11 -0
  37. package/dist/lib/superpowers-task-harness-drift.js +86 -0
  38. package/dist/lib/superpowers-task-protected-baseline.d.ts +10 -0
  39. package/dist/lib/superpowers-task-protected-baseline.js +47 -0
  40. package/dist/lib/superpowers-task-source-compile.js +93 -95
  41. package/dist/lib/superpowers-task-source-parser.js +1 -3
  42. package/dist/lib/superpowers-task-state-schema.d.ts +158 -3
  43. package/dist/lib/superpowers-task-state-schema.js +23 -1
  44. package/dist/lib/superpowers-task-state-shape.d.ts +3 -0
  45. package/dist/lib/superpowers-task-state-shape.js +50 -0
  46. package/dist/lib/superpowers-task-state.js +19 -39
  47. package/dist/lib/superpowers-task-status.js +11 -1
  48. package/dist/lib/superpowers-task-under-specified.d.ts +7 -0
  49. package/dist/lib/superpowers-task-under-specified.js +61 -0
  50. package/dist/lib/superpowers-task-validator.js +11 -37
  51. package/package.json +69 -69
  52. package/source-mappings.yaml +3 -0
@@ -0,0 +1,50 @@
1
+ import { isRecord } from "./superpowers-task-state-schema.js";
2
+ export function validateShape(state, errors) {
3
+ if (state.meta?.schema_version !== "superpowers-task-state-v1") {
4
+ errors.push("task-state.json schema_version must be superpowers-task-state-v1");
5
+ }
6
+ for (const key of [
7
+ "meta",
8
+ "sources",
9
+ "context",
10
+ "delivery",
11
+ "graph",
12
+ "attempts",
13
+ "current_attempt_id",
14
+ "required_command_specs",
15
+ "command_runs",
16
+ "negative_evidence_records",
17
+ "slices",
18
+ "evidence",
19
+ "gates",
20
+ "progress",
21
+ "blockers",
22
+ "final"
23
+ ]) {
24
+ if (!(key in state)) {
25
+ errors.push(`task-state.json is missing section: ${key}`);
26
+ }
27
+ }
28
+ }
29
+ export function hasUsableShape(state) {
30
+ const candidate = state;
31
+ return (isRecord(candidate.meta) &&
32
+ isRecord(candidate.sources) &&
33
+ isRecord(candidate.context) &&
34
+ isRecord(candidate.delivery) &&
35
+ isRecord(candidate.graph) &&
36
+ isRecord(candidate.graph.plan_items) &&
37
+ isRecord(candidate.graph.acceptance_criteria) &&
38
+ isRecord(candidate.graph.proof_layers) &&
39
+ Array.isArray(candidate.attempts) &&
40
+ typeof candidate.current_attempt_id === "string" &&
41
+ Array.isArray(candidate.required_command_specs) &&
42
+ Array.isArray(candidate.command_runs) &&
43
+ Array.isArray(candidate.negative_evidence_records) &&
44
+ Array.isArray(candidate.slices) &&
45
+ Array.isArray(candidate.evidence) &&
46
+ isRecord(candidate.gates) &&
47
+ isRecord(candidate.progress) &&
48
+ Array.isArray(candidate.blockers) &&
49
+ isRecord(candidate.final));
50
+ }
@@ -1,8 +1,10 @@
1
1
  import { createHash } from "node:crypto";
2
2
  import path from "node:path";
3
3
  import { ensureDir, pathExists, readText, writeTextIfChanged } from "./fs.js";
4
+ import { normalizeProofLayerId } from "./superpowers-task-fields.js";
4
5
  import { appendSuperpowersEvent } from "./superpowers-task-events.js";
5
- import { evaluateProofLayerAssertions, isMachineVerifiableLayer, normalizeAssertionResult, normalizeNegativeEvidenceScan } from "./superpowers-task-assertions.js";
6
+ import { evaluateProofLayerAssertions, isMachineVerifiableLayer } from "./superpowers-task-assertions.js";
7
+ import { readEvidenceRecords } from "./superpowers-task-evidence-records.js";
6
8
  import { SUPERPOWERS_TASK_STATE_JSON_SCHEMA, SUPERPOWERS_TASK_STATE_SCHEMA_VERSION, asStringArray, isRecord } from "./superpowers-task-state-schema.js";
7
9
  const SOURCE_FILES = {
8
10
  product_architecture_source: {
@@ -54,7 +56,15 @@ export async function initializeSuperpowersTask(workdir, options = {}) {
54
56
  full_population_required: null,
55
57
  representative_samples_validate: [],
56
58
  representative_samples_do_not_validate: [],
57
- out_of_scope_backlog: []
59
+ out_of_scope_backlog: [],
60
+ scope_fit_decision: "",
61
+ selected_scope_fit_slice: "",
62
+ owner_boundary: "",
63
+ primary_capability_path: "",
64
+ non_completing_outcomes: [],
65
+ assertion_policy: "",
66
+ source_authority: "",
67
+ product_goal: ""
58
68
  },
59
69
  scope_conflicts: []
60
70
  },
@@ -64,6 +74,11 @@ export async function initializeSuperpowersTask(workdir, options = {}) {
64
74
  proof_layers: {},
65
75
  edges: []
66
76
  },
77
+ attempts: [],
78
+ current_attempt_id: "",
79
+ required_command_specs: [],
80
+ command_runs: [],
81
+ negative_evidence_records: [],
67
82
  slices: [],
68
83
  evidence: [],
69
84
  gates: {},
@@ -121,8 +136,8 @@ export async function applySliceDelta(workdir, deltaFile) {
121
136
  missing_layer_classes: asStringArray(delta.missing_layer_classes),
122
137
  code_changes: asStringArray(delta.code_changes),
123
138
  evidence_records: evidenceRecords.map((item) => item.evidence_id),
124
- closed_layers: asStringArray(delta.closed_layers),
125
- remaining_layers: asStringArray(delta.remaining_layers),
139
+ closed_layers: asStringArray(delta.closed_layers).map(normalizeProofLayerId),
140
+ remaining_layers: asStringArray(delta.remaining_layers).map(normalizeProofLayerId),
126
141
  blockers: Array.isArray(delta.blockers) ? delta.blockers : [],
127
142
  cleanup_assertions: asStringArray(delta.cleanup_assertions),
128
143
  progress_value: {
@@ -205,41 +220,6 @@ export function sha256(value) {
205
220
  export function stableJson(value) {
206
221
  return JSON.stringify(sortJson(value), null, 2);
207
222
  }
208
- function readEvidenceRecords(value) {
209
- if (!Array.isArray(value)) {
210
- return [];
211
- }
212
- return value.filter(isRecord).map((item) => ({
213
- evidence_id: String(item.evidence_id ?? item.evidenceId ?? ""),
214
- slice_id: String(item.slice_id ?? item.sliceId ?? ""),
215
- type: String(item.type ?? ""),
216
- freshness: isRecord(item.freshness)
217
- ? {
218
- created_at: String(item.freshness.created_at ?? ""),
219
- valid_for: String(item.freshness.valid_for ?? ""),
220
- stale_after: item.freshness.stale_after === null ? null : item.freshness.stale_after === undefined ? null : String(item.freshness.stale_after)
221
- }
222
- : { created_at: "", valid_for: "", stale_after: null },
223
- command: item.command === undefined ? undefined : String(item.command),
224
- command_exit_code: item.command_exit_code === undefined ? undefined : Number(item.command_exit_code),
225
- artifact_paths: asStringArray(item.artifact_paths),
226
- proves: asStringArray(item.proves),
227
- does_not_prove: asStringArray(item.does_not_prove),
228
- redaction: isRecord(item.redaction)
229
- ? { checked: item.redaction.checked === true, contains_secret: item.redaction.contains_secret === true }
230
- : { checked: false, contains_secret: false },
231
- reviewability: isRecord(item.reviewability)
232
- ? {
233
- external_reviewer_can_reproduce: item.reviewability.external_reviewer_can_reproduce === true,
234
- reproduction_steps: String(item.reviewability.reproduction_steps ?? "")
235
- }
236
- : { external_reviewer_can_reproduce: false, reproduction_steps: "" },
237
- assertion_result: normalizeAssertionResult(item.assertion_result),
238
- negative_evidence_scan: normalizeNegativeEvidenceScan(item.negative_evidence_scan),
239
- sibling_substitution_used: item.sibling_substitution_used === true,
240
- sibling_substitution_approval_source: item.sibling_substitution_approval_source === undefined ? undefined : String(item.sibling_substitution_approval_source)
241
- }));
242
- }
243
223
  function sortJson(value) {
244
224
  if (Array.isArray(value)) {
245
225
  return value.map(sortJson);
@@ -1,5 +1,15 @@
1
1
  const CANONICAL_PLAN_STATUSES = new Set(["not_started", "in_progress", "partial", "blocked", "invalidated", "complete", "out_of_scope_NA"]);
2
- const CANONICAL_AC_STATUSES = new Set(["not_started", "not_run", "in_progress", "partial", "blocked", "invalidated", "complete", "out_of_scope_NA"]);
2
+ const CANONICAL_AC_STATUSES = new Set([
3
+ "not_started",
4
+ "not_run",
5
+ "in_progress",
6
+ "partial",
7
+ "blocked",
8
+ "invalidated",
9
+ "under_specified",
10
+ "complete",
11
+ "out_of_scope_NA"
12
+ ]);
3
13
  export function validateCanonicalStatuses(state, errors) {
4
14
  for (const [planId, item] of Object.entries(state.graph?.plan_items ?? {})) {
5
15
  if (!CANONICAL_PLAN_STATUSES.has(item.status)) {
@@ -0,0 +1,7 @@
1
+ import type { SuperpowersAcceptanceCriterion, SuperpowersTaskState } from "./superpowers-task-state-schema.js";
2
+ export interface UnderSpecifiedAc {
3
+ ac_id: string;
4
+ reasons: string[];
5
+ }
6
+ export declare function findUnderSpecifiedAcs(state: SuperpowersTaskState): UnderSpecifiedAc[];
7
+ export declare function underSpecifiedReasons(acId: string, ac: SuperpowersAcceptanceCriterion): string[];
@@ -0,0 +1,61 @@
1
+ import { isMachineVerifiableLayer } from "./superpowers-task-assertions.js";
2
+ const GENERATED_ONLY_EVIDENCE = /\b(matrix|verdict|validator|final[-_ ]?card|final[-_ ]?summary|evidence[-_ ]?index|derived\/)/i;
3
+ const MACHINE_UI_PROOF = /\b(browser|ui_browser|e2e|smoke|trace|playwright|route|owner surface)\b/i;
4
+ const MANUAL_ONLY_TEST = /\b(查看页面|人工确认|manual confirm|manually inspect|visual check only)\b/i;
5
+ export function findUnderSpecifiedAcs(state) {
6
+ return Object.entries(state.graph?.acceptance_criteria ?? {})
7
+ .map(([acId, ac]) => ({ ac_id: acId, reasons: underSpecifiedReasons(acId, ac) }))
8
+ .filter((item) => item.reasons.length > 0);
9
+ }
10
+ export function underSpecifiedReasons(acId, ac) {
11
+ if (ac.machine_blocking !== true && ac.assertion_result_required !== true) {
12
+ return [];
13
+ }
14
+ const reasons = [];
15
+ if (!trimmed(ac.assertion_command)) {
16
+ reasons.push(`${acId} under_specified: assertion_command is required for machine_blocking AC`);
17
+ }
18
+ if ((ac.assertion_artifacts ?? []).length === 0) {
19
+ reasons.push(`${acId} under_specified: assertion_artifacts are required for machine_blocking AC`);
20
+ }
21
+ if ((ac.positive_assertions ?? []).length === 0) {
22
+ reasons.push(`${acId} under_specified: positive_assertions are required for machine_blocking AC`);
23
+ }
24
+ if ((ac.negative_assertions ?? []).length === 0) {
25
+ reasons.push(`${acId} under_specified: negative_assertions are required for machine_blocking AC`);
26
+ }
27
+ if ((ac.invalid_completion_signals ?? []).length === 0) {
28
+ reasons.push(`${acId} under_specified: invalid_completion_signals are required for machine_blocking AC`);
29
+ }
30
+ if (ac.assertion_result_required !== true) {
31
+ reasons.push(`${acId} under_specified: machine_blocking AC must require assertion_result`);
32
+ }
33
+ const requiredLayers = ac.required_proof_layers ?? [];
34
+ if (requiredLayers.some((layer) => isMachineVerifiableLayer(`${acId}.${layer}`)) && !trimmed(ac.assertion_command)) {
35
+ reasons.push(`${acId} under_specified: machine proof layers cannot produce assertion_result without assertion_command`);
36
+ }
37
+ if (requiredLayers.includes("ui_browser") && !MACHINE_UI_PROOF.test(acEvidenceText(ac))) {
38
+ reasons.push(`${acId} under_specified: ui_browser AC requires browser/e2e/smoke/trace-backed proof`);
39
+ }
40
+ const finalEvidence = ac.final_evidence_expected ?? [];
41
+ if (finalEvidence.length > 0 && finalEvidence.every((item) => GENERATED_ONLY_EVIDENCE.test(item))) {
42
+ reasons.push(`${acId} under_specified: final_evidence_expected only names generated summary artifacts`);
43
+ }
44
+ const testCases = ac.test_cases ?? [];
45
+ if (testCases.length > 0 && testCases.every((item) => MANUAL_ONLY_TEST.test(item))) {
46
+ reasons.push(`${acId} under_specified: test_cases are manual-only`);
47
+ }
48
+ return reasons;
49
+ }
50
+ function acEvidenceText(ac) {
51
+ return [
52
+ ac.assertion_command ?? "",
53
+ ...(ac.assertion_artifacts ?? []),
54
+ ...(ac.verification_method ?? []),
55
+ ...(ac.test_cases ?? []),
56
+ ...(ac.final_evidence_expected ?? [])
57
+ ].join("\n");
58
+ }
59
+ function trimmed(value) {
60
+ return Boolean(value && value.trim());
61
+ }
@@ -4,11 +4,14 @@ import { findSensitiveEvidence } from "./plan-acceptance-evidence.js";
4
4
  import { primitiveText, repoRelative, resolveInputDir } from "./plan-validator-common.js";
5
5
  import { derivedMatchesState } from "./superpowers-task-derive.js";
6
6
  import { validatePlanCompletionConformance } from "./superpowers-task-conformance.js";
7
+ import { scanSuperpowersContradictions } from "./superpowers-task-contradictions.js";
8
+ import { evaluateTrustedEvidenceKernel } from "./superpowers-task-evidence-kernel.js";
7
9
  import { fullPopulationRequired, validateDeliveryContract, validateScopeConflicts } from "./superpowers-task-delivery.js";
10
+ import { hasUsableShape, validateShape } from "./superpowers-task-state-shape.js";
8
11
  import { loadSuperpowersState, sha256 } from "./superpowers-task-state.js";
9
12
  import { validateCanonicalStatuses } from "./superpowers-task-status.js";
10
13
  import { isRecord } from "./superpowers-task-state-schema.js";
11
- import { evaluateProofLayerAssertions, isUiBrowserLayer } from "./superpowers-task-assertions.js";
14
+ import { evaluateProofLayerAssertions, isUiBrowserLayer, proofLayerName } from "./superpowers-task-assertions.js";
12
15
  export async function validateSuperpowersState(projectRoot, args = []) {
13
16
  const info = [];
14
17
  const warnings = [];
@@ -24,12 +27,7 @@ export async function validateSuperpowersState(projectRoot, args = []) {
24
27
  state = await loadSuperpowersState(targetDir);
25
28
  }
26
29
  catch (error) {
27
- return {
28
- info,
29
- warnings,
30
- hygiene,
31
- errors: [`${repoRelative(projectRoot, statePath)} is not valid JSON: ${error instanceof Error ? error.message : String(error)}`]
32
- };
30
+ return { info, warnings, hygiene, errors: [`${repoRelative(projectRoot, statePath)} is not valid JSON: ${error instanceof Error ? error.message : String(error)}`] };
33
31
  }
34
32
  validateShape(state, errors);
35
33
  if (!hasUsableShape(state)) {
@@ -44,6 +42,8 @@ export async function validateSuperpowersState(projectRoot, args = []) {
44
42
  validateScopeConflicts(state, errors);
45
43
  validateEvidenceRecords(state, errors);
46
44
  validateProofLayers(state, errors);
45
+ errors.push(...(await evaluateTrustedEvidenceKernel(targetDir, state)).errors);
46
+ errors.push(...(await scanSuperpowersContradictions(targetDir, state)).errors);
47
47
  validateAuditor(state, errors);
48
48
  validateFinalCompletion(state, errors);
49
49
  errors.push(...(await derivedMatchesState(targetDir, state)));
@@ -66,33 +66,6 @@ async function validateSourceHashes(workdir, state, errors) {
66
66
  }
67
67
  }
68
68
  }
69
- function validateShape(state, errors) {
70
- if (state.meta?.schema_version !== "superpowers-task-state-v1") {
71
- errors.push("task-state.json schema_version must be superpowers-task-state-v1");
72
- }
73
- for (const key of ["meta", "sources", "context", "delivery", "graph", "slices", "evidence", "gates", "progress", "blockers", "final"]) {
74
- if (!(key in state)) {
75
- errors.push(`task-state.json is missing section: ${key}`);
76
- }
77
- }
78
- }
79
- function hasUsableShape(state) {
80
- const candidate = state;
81
- return (isRecord(candidate.meta) &&
82
- isRecord(candidate.sources) &&
83
- isRecord(candidate.context) &&
84
- isRecord(candidate.delivery) &&
85
- isRecord(candidate.graph) &&
86
- isRecord(candidate.graph.plan_items) &&
87
- isRecord(candidate.graph.acceptance_criteria) &&
88
- isRecord(candidate.graph.proof_layers) &&
89
- Array.isArray(candidate.slices) &&
90
- Array.isArray(candidate.evidence) &&
91
- isRecord(candidate.gates) &&
92
- isRecord(candidate.progress) &&
93
- Array.isArray(candidate.blockers) &&
94
- isRecord(candidate.final));
95
- }
96
69
  function validateGraphReferences(state, errors) {
97
70
  const planIds = new Set(Object.keys(state.graph?.plan_items ?? {}));
98
71
  const acIds = new Set(Object.keys(state.graph?.acceptance_criteria ?? {}));
@@ -165,10 +138,11 @@ function validateEvidenceRecords(state, errors) {
165
138
  errors.push(`${label} uses sibling substitution without approval`);
166
139
  }
167
140
  for (const proofLayer of evidence.proves ?? []) {
168
- if (proofLayer.endsWith(".runtime") && /\b(mock|unit|viewmodel)\b/i.test(evidence.type)) {
169
- errors.push(`${label} runtime proof cannot be mock/unit/viewmodel only`);
141
+ const layerName = proofLayerName(proofLayer);
142
+ if (layerName === "worker_runtime" && /\b(mock|unit|viewmodel)\b/i.test(evidence.type)) {
143
+ errors.push(`${label} worker_runtime proof cannot be mock/unit/viewmodel only`);
170
144
  }
171
- if (proofLayer.endsWith(".ui_browser") && !/(browser|ui_browser|screenshot|playwright)/i.test(evidence.type)) {
145
+ if (layerName === "ui_browser" && !/(browser|ui_browser|screenshot|playwright)/i.test(evidence.type)) {
172
146
  errors.push(`${label} UI proof must use browser owner surface evidence`);
173
147
  }
174
148
  }
package/package.json CHANGED
@@ -1,69 +1,69 @@
1
- {
2
- "name": "project-tiny-context-harness",
3
- "version": "0.2.81",
4
- "description": "Minimal project memory and validation harness for AI coding agents.",
5
- "license": "MIT",
6
- "author": "Seven128",
7
- "homepage": "https://github.com/Seven128/project-tiny-context-harness#readme",
8
- "repository": {
9
- "type": "git",
10
- "url": "git+https://github.com/Seven128/project-tiny-context-harness.git",
11
- "directory": "packages/ty-context"
12
- },
13
- "bugs": {
14
- "url": "https://github.com/Seven128/project-tiny-context-harness/issues"
15
- },
16
- "keywords": [
17
- "ai-agents",
18
- "coding-agent",
19
- "codex",
20
- "claude-code",
21
- "cursor",
22
- "gemini-cli",
23
- "opencode",
24
- "agent-context",
25
- "context-engineering",
26
- "context-management",
27
- "agents-md",
28
- "project-memory",
29
- "agent-memory",
30
- "ai-coding",
31
- "multi-agent",
32
- "llm",
33
- "developer-tools",
34
- "developer-productivity",
35
- "cli",
36
- "ty-context",
37
- "workflow"
38
- ],
39
- "type": "module",
40
- "bin": {
41
- "ty-context": "dist/cli.js"
42
- },
43
- "files": [
44
- "README.md",
45
- "dist",
46
- "assets",
47
- "migrations",
48
- "source-mappings.yaml"
49
- ],
50
- "scripts": {
51
- "build": "node -e \"require('node:fs').rmSync('dist',{recursive:true,force:true})\" && tsc -p tsconfig.json",
52
- "typecheck": "tsc -p tsconfig.json --noEmit",
53
- "test:built": "node --test ../../tests/ty-context/*.test.mjs",
54
- "test": "npm run build && node --test ../../tests/ty-context/*.test.mjs",
55
- "prepack": "npm run build"
56
- },
57
- "engines": {
58
- "node": ">=24"
59
- },
60
- "dependencies": {
61
- "@google/design.md": "^0.3.0",
62
- "impeccable": "^3.1.0",
63
- "yaml": "^2.9.0"
64
- },
65
- "devDependencies": {
66
- "@types/node": "^26.0.0",
67
- "typescript": "^5.5.0"
68
- }
69
- }
1
+ {
2
+ "name": "project-tiny-context-harness",
3
+ "version": "0.2.83",
4
+ "description": "Minimal project memory and validation harness for AI coding agents.",
5
+ "license": "MIT",
6
+ "author": "Seven128",
7
+ "homepage": "https://github.com/Seven128/project-tiny-context-harness#readme",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/Seven128/project-tiny-context-harness.git",
11
+ "directory": "packages/ty-context"
12
+ },
13
+ "bugs": {
14
+ "url": "https://github.com/Seven128/project-tiny-context-harness/issues"
15
+ },
16
+ "keywords": [
17
+ "ai-agents",
18
+ "coding-agent",
19
+ "codex",
20
+ "claude-code",
21
+ "cursor",
22
+ "gemini-cli",
23
+ "opencode",
24
+ "agent-context",
25
+ "context-engineering",
26
+ "context-management",
27
+ "agents-md",
28
+ "project-memory",
29
+ "agent-memory",
30
+ "ai-coding",
31
+ "multi-agent",
32
+ "llm",
33
+ "developer-tools",
34
+ "developer-productivity",
35
+ "cli",
36
+ "ty-context",
37
+ "workflow"
38
+ ],
39
+ "type": "module",
40
+ "bin": {
41
+ "ty-context": "dist/cli.js"
42
+ },
43
+ "files": [
44
+ "README.md",
45
+ "dist",
46
+ "assets",
47
+ "migrations",
48
+ "source-mappings.yaml"
49
+ ],
50
+ "scripts": {
51
+ "build": "node -e \"require('node:fs').rmSync('dist',{recursive:true,force:true})\" && tsc -p tsconfig.json",
52
+ "typecheck": "tsc -p tsconfig.json --noEmit",
53
+ "test:built": "node --test ../../tests/ty-context/*.test.mjs",
54
+ "test": "npm run build && node --test ../../tests/ty-context/*.test.mjs",
55
+ "prepack": "npm run build"
56
+ },
57
+ "engines": {
58
+ "node": ">=24"
59
+ },
60
+ "dependencies": {
61
+ "@google/design.md": "^0.3.0",
62
+ "impeccable": "^3.1.0",
63
+ "yaml": "^2.9.0"
64
+ },
65
+ "devDependencies": {
66
+ "@types/node": "^26.0.0",
67
+ "typescript": "^5.5.0"
68
+ }
69
+ }
@@ -17,6 +17,9 @@ source_mappings:
17
17
  - source: ".codex/ty-context-managed/make/ty-context.mk"
18
18
  target: "packages/ty-context/assets/make/ty-context.mk"
19
19
  mode: "copy-file"
20
+ - source: ".codex/ty-context-managed/protected-harness-baseline.json"
21
+ target: "packages/ty-context/assets/protected-harness-baseline.json"
22
+ mode: "copy-file"
20
23
  - source: ".codex/ty-context-managed/minimal_tools"
21
24
  target: "packages/ty-context/assets/tools"
22
25
  mode: "copy-tree"