@codeledger/cli 0.5.0 → 0.6.0

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 (124) hide show
  1. package/dist/artifacts/summary.d.ts +6 -0
  2. package/dist/artifacts/summary.d.ts.map +1 -0
  3. package/dist/artifacts/summary.js +49 -0
  4. package/dist/artifacts/summary.js.map +1 -0
  5. package/dist/commands/activate.d.ts.map +1 -1
  6. package/dist/commands/activate.js +64 -23
  7. package/dist/commands/activate.js.map +1 -1
  8. package/dist/commands/bundle.d.ts.map +1 -1
  9. package/dist/commands/bundle.js +28 -5
  10. package/dist/commands/bundle.js.map +1 -1
  11. package/dist/commands/init.d.ts.map +1 -1
  12. package/dist/commands/init.js +10 -12
  13. package/dist/commands/init.js.map +1 -1
  14. package/dist/commands/intent.d.ts.map +1 -1
  15. package/dist/commands/intent.js +17 -2
  16. package/dist/commands/intent.js.map +1 -1
  17. package/dist/commands/manifest.d.ts +8 -0
  18. package/dist/commands/manifest.d.ts.map +1 -0
  19. package/dist/commands/manifest.js +144 -0
  20. package/dist/commands/manifest.js.map +1 -0
  21. package/dist/commands/policy.d.ts +8 -0
  22. package/dist/commands/policy.d.ts.map +1 -0
  23. package/dist/commands/policy.js +27 -0
  24. package/dist/commands/policy.js.map +1 -0
  25. package/dist/commands/progress-check.d.ts +14 -0
  26. package/dist/commands/progress-check.d.ts.map +1 -0
  27. package/dist/commands/progress-check.js +153 -0
  28. package/dist/commands/progress-check.js.map +1 -0
  29. package/dist/commands/review-coverage.d.ts +12 -0
  30. package/dist/commands/review-coverage.d.ts.map +1 -0
  31. package/dist/commands/review-coverage.js +142 -0
  32. package/dist/commands/review-coverage.js.map +1 -0
  33. package/dist/commands/review-gate.d.ts +12 -0
  34. package/dist/commands/review-gate.d.ts.map +1 -0
  35. package/dist/commands/review-gate.js +130 -0
  36. package/dist/commands/review-gate.js.map +1 -0
  37. package/dist/commands/session-summary.d.ts.map +1 -1
  38. package/dist/commands/session-summary.js +39 -5
  39. package/dist/commands/session-summary.js.map +1 -1
  40. package/dist/commands/setup-ci.d.ts +9 -0
  41. package/dist/commands/setup-ci.d.ts.map +1 -0
  42. package/dist/commands/setup-ci.js +139 -0
  43. package/dist/commands/setup-ci.js.map +1 -0
  44. package/dist/commands/sign-manifest.d.ts +8 -0
  45. package/dist/commands/sign-manifest.d.ts.map +1 -0
  46. package/dist/commands/sign-manifest.js +58 -0
  47. package/dist/commands/sign-manifest.js.map +1 -0
  48. package/dist/commands/vendor.d.ts +20 -0
  49. package/dist/commands/vendor.d.ts.map +1 -0
  50. package/dist/commands/vendor.js +157 -0
  51. package/dist/commands/vendor.js.map +1 -0
  52. package/dist/commands/verify.d.ts +13 -0
  53. package/dist/commands/verify.d.ts.map +1 -0
  54. package/dist/commands/verify.js +288 -0
  55. package/dist/commands/verify.js.map +1 -0
  56. package/dist/index.d.ts.map +1 -1
  57. package/dist/index.js +98 -2
  58. package/dist/index.js.map +1 -1
  59. package/dist/integrations/github-actions.d.ts +17 -0
  60. package/dist/integrations/github-actions.d.ts.map +1 -0
  61. package/dist/integrations/github-actions.js +64 -0
  62. package/dist/integrations/github-actions.js.map +1 -0
  63. package/dist/manifest/build.d.ts +19 -0
  64. package/dist/manifest/build.d.ts.map +1 -0
  65. package/dist/manifest/build.js +82 -0
  66. package/dist/manifest/build.js.map +1 -0
  67. package/dist/manifest/schema.d.ts +2 -0
  68. package/dist/manifest/schema.d.ts.map +1 -0
  69. package/dist/manifest/schema.js +2 -0
  70. package/dist/manifest/schema.js.map +1 -0
  71. package/dist/manifest/write.d.ts +13 -0
  72. package/dist/manifest/write.d.ts.map +1 -0
  73. package/dist/manifest/write.js +69 -0
  74. package/dist/manifest/write.js.map +1 -0
  75. package/dist/policy/load.d.ts +21 -0
  76. package/dist/policy/load.d.ts.map +1 -0
  77. package/dist/policy/load.js +63 -0
  78. package/dist/policy/load.js.map +1 -0
  79. package/dist/policy/resolve.d.ts +18 -0
  80. package/dist/policy/resolve.d.ts.map +1 -0
  81. package/dist/policy/resolve.js +86 -0
  82. package/dist/policy/resolve.js.map +1 -0
  83. package/dist/policy/schema.d.ts +22 -0
  84. package/dist/policy/schema.d.ts.map +1 -0
  85. package/dist/policy/schema.js +82 -0
  86. package/dist/policy/schema.js.map +1 -0
  87. package/dist/session-paths.d.ts +6 -0
  88. package/dist/session-paths.d.ts.map +1 -1
  89. package/dist/session-paths.js +12 -0
  90. package/dist/session-paths.js.map +1 -1
  91. package/dist/signing/canonicalize.d.ts +17 -0
  92. package/dist/signing/canonicalize.d.ts.map +1 -0
  93. package/dist/signing/canonicalize.js +50 -0
  94. package/dist/signing/canonicalize.js.map +1 -0
  95. package/dist/signing/hmac.d.ts +8 -0
  96. package/dist/signing/hmac.d.ts.map +1 -0
  97. package/dist/signing/hmac.js +16 -0
  98. package/dist/signing/hmac.js.map +1 -0
  99. package/dist/signing/signer.d.ts +16 -0
  100. package/dist/signing/signer.d.ts.map +1 -0
  101. package/dist/signing/signer.js +2 -0
  102. package/dist/signing/signer.js.map +1 -0
  103. package/dist/templates/claude-md.d.ts.map +1 -1
  104. package/dist/templates/claude-md.js +61 -3
  105. package/dist/templates/claude-md.js.map +1 -1
  106. package/dist/templates/config.d.ts.map +1 -1
  107. package/dist/templates/config.js +3 -0
  108. package/dist/templates/config.js.map +1 -1
  109. package/dist/templates/hooks.d.ts.map +1 -1
  110. package/dist/templates/hooks.js +35 -2
  111. package/dist/templates/hooks.js.map +1 -1
  112. package/dist/verify/evaluate.d.ts +10 -0
  113. package/dist/verify/evaluate.d.ts.map +1 -0
  114. package/dist/verify/evaluate.js +117 -0
  115. package/dist/verify/evaluate.js.map +1 -0
  116. package/dist/verify/policy-snapshot.d.ts +7 -0
  117. package/dist/verify/policy-snapshot.d.ts.map +1 -0
  118. package/dist/verify/policy-snapshot.js +36 -0
  119. package/dist/verify/policy-snapshot.js.map +1 -0
  120. package/dist/verify/report.d.ts +11 -0
  121. package/dist/verify/report.d.ts.map +1 -0
  122. package/dist/verify/report.js +64 -0
  123. package/dist/verify/report.js.map +1 -0
  124. package/package.json +10 -10
@@ -0,0 +1,10 @@
1
+ import type { ResolvedPolicyV1, ContextManifestV1, ViolationV1, CoverageAttestationV1 } from '@codeledger/types';
2
+ /**
3
+ * Evaluate a manifest against a resolved policy. Returns violations sorted
4
+ * by code then path for deterministic output.
5
+ *
6
+ * This function does NOT make pass/fail decisions — it only detects violations.
7
+ * The calling code decides exit codes based on policy mode.
8
+ */
9
+ export declare function evaluatePolicy(manifest: ContextManifestV1, policy: ResolvedPolicyV1, coverageAttestation?: CoverageAttestationV1): ViolationV1[];
10
+ //# sourceMappingURL=evaluate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"evaluate.d.ts","sourceRoot":"","sources":["../../src/verify/evaluate.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,gBAAgB,EAChB,iBAAiB,EACjB,WAAW,EACX,qBAAqB,EACtB,MAAM,mBAAmB,CAAC;AAE3B;;;;;;GAMG;AACH,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,iBAAiB,EAC3B,MAAM,EAAE,gBAAgB,EACxB,mBAAmB,CAAC,EAAE,qBAAqB,GAC1C,WAAW,EAAE,CAsGf"}
@@ -0,0 +1,117 @@
1
+ /**
2
+ * Evaluate a manifest against a resolved policy. Returns violations sorted
3
+ * by code then path for deterministic output.
4
+ *
5
+ * This function does NOT make pass/fail decisions — it only detects violations.
6
+ * The calling code decides exit codes based on policy mode.
7
+ */
8
+ export function evaluatePolicy(manifest, policy, coverageAttestation) {
9
+ const violations = [];
10
+ // LOW_CONFIDENCE — overall_confidence < min_confidence
11
+ if (manifest.confidence.overall < policy.min_confidence) {
12
+ violations.push({
13
+ code: 'LOW_CONFIDENCE',
14
+ message: `Overall confidence ${manifest.confidence.overall.toFixed(2)} below minimum ${policy.min_confidence.toFixed(2)}`,
15
+ value: manifest.confidence.overall,
16
+ threshold: policy.min_confidence,
17
+ });
18
+ }
19
+ // HIGH_DRIFT — drift_score > max_drift
20
+ if (manifest.intent.drift_score > policy.max_drift) {
21
+ violations.push({
22
+ code: 'HIGH_DRIFT',
23
+ message: `Drift score ${manifest.intent.drift_score.toFixed(2)} exceeds maximum ${policy.max_drift.toFixed(2)}`,
24
+ value: manifest.intent.drift_score,
25
+ threshold: policy.max_drift,
26
+ });
27
+ }
28
+ // DENY_PATH_MATCH — selected file matches deny_paths pattern
29
+ for (const file of manifest.bundle.files) {
30
+ for (const pattern of policy.deny_paths) {
31
+ if (matchDenyPattern(file.path, pattern)) {
32
+ violations.push({
33
+ code: 'DENY_PATH_MATCH',
34
+ message: `Selected file ${file.path} matches deny pattern ${pattern}`,
35
+ path: file.path,
36
+ pattern,
37
+ });
38
+ }
39
+ }
40
+ }
41
+ // MISSING_TESTS — test_presence below threshold when require_tests is true
42
+ if (policy.require_tests) {
43
+ const testPresence = manifest.confidence.envelope.test_presence;
44
+ // require_tests uses a fixed threshold of 0.50
45
+ const threshold = 0.50;
46
+ if (testPresence < threshold) {
47
+ violations.push({
48
+ code: 'MISSING_TESTS',
49
+ message: `Test presence ${testPresence.toFixed(2)} below required threshold ${threshold.toFixed(2)}`,
50
+ value: testPresence,
51
+ threshold,
52
+ });
53
+ }
54
+ }
55
+ // BUNDLE_TOO_LARGE — file count or byte count exceeds policy limits
56
+ if (manifest.bundle.file_count > policy.bundle_max_files) {
57
+ violations.push({
58
+ code: 'BUNDLE_TOO_LARGE',
59
+ message: `Bundle file count ${manifest.bundle.file_count} exceeds limit ${policy.bundle_max_files}`,
60
+ dimension: 'file_count',
61
+ value: manifest.bundle.file_count,
62
+ threshold: policy.bundle_max_files,
63
+ });
64
+ }
65
+ if (manifest.bundle.total_bytes > policy.bundle_max_bytes) {
66
+ violations.push({
67
+ code: 'BUNDLE_TOO_LARGE',
68
+ message: `Bundle byte size ${manifest.bundle.total_bytes} exceeds limit ${policy.bundle_max_bytes}`,
69
+ dimension: 'byte_size',
70
+ value: manifest.bundle.total_bytes,
71
+ threshold: policy.bundle_max_bytes,
72
+ });
73
+ }
74
+ // INSUFFICIENT_COVERAGE — review coverage below policy minimum
75
+ if (coverageAttestation && policy.min_review_coverage !== undefined) {
76
+ if (coverageAttestation.file_coverage < policy.min_review_coverage) {
77
+ violations.push({
78
+ code: 'INSUFFICIENT_COVERAGE',
79
+ message: `Review file coverage ${coverageAttestation.file_coverage.toFixed(2)} below minimum ${policy.min_review_coverage.toFixed(2)}`,
80
+ value: coverageAttestation.file_coverage,
81
+ threshold: policy.min_review_coverage,
82
+ });
83
+ }
84
+ }
85
+ // POST_HOC_READS — reads that occurred after claims were written
86
+ if (coverageAttestation && policy.block_post_hoc_reads && coverageAttestation.post_hoc_read_count > 0) {
87
+ violations.push({
88
+ code: 'POST_HOC_READS',
89
+ message: `${coverageAttestation.post_hoc_read_count} file(s) were read after review claims were written`,
90
+ value: coverageAttestation.post_hoc_read_count,
91
+ });
92
+ }
93
+ // Sort by code, then by path (if present) for deterministic output
94
+ violations.sort((a, b) => {
95
+ const codeCmp = a.code.localeCompare(b.code);
96
+ if (codeCmp !== 0)
97
+ return codeCmp;
98
+ return (a.path ?? '').localeCompare(b.path ?? '');
99
+ });
100
+ return violations;
101
+ }
102
+ /**
103
+ * Match a file path against a deny pattern.
104
+ * Supports simple glob patterns with * wildcard.
105
+ */
106
+ function matchDenyPattern(filePath, pattern) {
107
+ // Convert glob pattern to regex
108
+ const escaped = pattern
109
+ .replace(/[.+^${}()|[\]\\]/g, '\\$&')
110
+ .replace(/\*/g, '.*');
111
+ const regex = new RegExp(`^${escaped}$|/${escaped}$|^${escaped}/|/${escaped}/`);
112
+ // Also match against the basename
113
+ const basename = filePath.split('/').pop() ?? filePath;
114
+ const baseRegex = new RegExp(`^${escaped}$`);
115
+ return regex.test(filePath) || baseRegex.test(basename);
116
+ }
117
+ //# sourceMappingURL=evaluate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"evaluate.js","sourceRoot":"","sources":["../../src/verify/evaluate.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import type { ResolvedPolicyV1 } from '@codeledger/types';
2
+ /**
3
+ * Build and write a policy snapshot — records the resolved policy used
4
+ * during a verify run, including its hash for audit trail.
5
+ */
6
+ export declare function writePolicySnapshot(policy: ResolvedPolicyV1, outPath: string): void;
7
+ //# sourceMappingURL=policy-snapshot.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"policy-snapshot.d.ts","sourceRoot":"","sources":["../../src/verify/policy-snapshot.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,gBAAgB,EAAqC,MAAM,mBAAmB,CAAC;AAG7F;;;GAGG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,gBAAgB,EACxB,OAAO,EAAE,MAAM,GACd,IAAI,CA6BN"}
@@ -0,0 +1,36 @@
1
+ import { createHash } from 'node:crypto';
2
+ import { writeFileSync, mkdirSync } from 'node:fs';
3
+ import { dirname } from 'node:path';
4
+ import { canonicalize } from '../signing/canonicalize.js';
5
+ /**
6
+ * Build and write a policy snapshot — records the resolved policy used
7
+ * during a verify run, including its hash for audit trail.
8
+ */
9
+ export function writePolicySnapshot(policy, outPath) {
10
+ // Strip resolved_from to get the base policy for hashing
11
+ const basePolicyForHash = {
12
+ schema_version: policy.schema_version,
13
+ mode: policy.mode,
14
+ min_confidence: policy.min_confidence,
15
+ max_drift: policy.max_drift,
16
+ require_tests: policy.require_tests,
17
+ deny_paths: policy.deny_paths,
18
+ bundle_max_files: policy.bundle_max_files,
19
+ bundle_max_bytes: policy.bundle_max_bytes,
20
+ redact_actor_identity: policy.redact_actor_identity,
21
+ store_file_paths: policy.store_file_paths,
22
+ };
23
+ const hash = createHash('sha256')
24
+ .update(canonicalize(basePolicyForHash))
25
+ .digest('hex');
26
+ const snapshot = {
27
+ schema_version: 'mustang/policy-snapshot/v1',
28
+ policy: basePolicyForHash,
29
+ hash,
30
+ resolved_from: policy.resolved_from,
31
+ resolved_at: new Date().toISOString(),
32
+ };
33
+ mkdirSync(dirname(outPath), { recursive: true });
34
+ writeFileSync(outPath, JSON.stringify(snapshot, null, 2) + '\n');
35
+ }
36
+ //# sourceMappingURL=policy-snapshot.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"policy-snapshot.js","sourceRoot":"","sources":["../../src/verify/policy-snapshot.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAE1D;;;GAGG;AACH,MAAM,UAAU,mBAAmB,CACjC,MAAwB,EACxB,OAAe;IAEf,yDAAyD;IACzD,MAAM,iBAAiB,GAAoB;QACzC,cAAc,EAAE,MAAM,CAAC,cAAc;QACrC,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,cAAc,EAAE,MAAM,CAAC,cAAc;QACrC,SAAS,EAAE,MAAM,CAAC,SAAS;QAC3B,aAAa,EAAE,MAAM,CAAC,aAAa;QACnC,UAAU,EAAE,MAAM,CAAC,UAAU;QAC7B,gBAAgB,EAAE,MAAM,CAAC,gBAAgB;QACzC,gBAAgB,EAAE,MAAM,CAAC,gBAAgB;QACzC,qBAAqB,EAAE,MAAM,CAAC,qBAAqB;QACnD,gBAAgB,EAAE,MAAM,CAAC,gBAAgB;KAC1C,CAAC;IAEF,MAAM,IAAI,GAAG,UAAU,CAAC,QAAQ,CAAC;SAC9B,MAAM,CAAC,YAAY,CAAC,iBAAiB,CAAC,CAAC;SACvC,MAAM,CAAC,KAAK,CAAC,CAAC;IAEjB,MAAM,QAAQ,GAAqB;QACjC,cAAc,EAAE,4BAA4B;QAC5C,MAAM,EAAE,iBAAiB;QACzB,IAAI;QACJ,aAAa,EAAE,MAAM,CAAC,aAAa;QACnC,WAAW,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;KACtC,CAAC;IAEF,SAAS,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACjD,aAAa,CAAC,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;AACnE,CAAC"}
@@ -0,0 +1,11 @@
1
+ import type { ContextManifestV1, ResolvedPolicyV1, ViolationV1, VerifyReportV1 } from '@codeledger/types';
2
+ /**
3
+ * Build a verify report from manifest, policy, and violations.
4
+ */
5
+ export declare function buildVerifyReport(opts: {
6
+ manifest: ContextManifestV1;
7
+ policy: ResolvedPolicyV1;
8
+ violations: ViolationV1[];
9
+ codeledgerVersion: string;
10
+ }): VerifyReportV1;
11
+ //# sourceMappingURL=report.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"report.d.ts","sourceRoot":"","sources":["../../src/verify/report.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,iBAAiB,EACjB,gBAAgB,EAChB,WAAW,EACX,cAAc,EAEf,MAAM,mBAAmB,CAAC;AAI3B;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE;IACtC,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,MAAM,EAAE,gBAAgB,CAAC;IACzB,UAAU,EAAE,WAAW,EAAE,CAAC;IAC1B,iBAAiB,EAAE,MAAM,CAAC;CAC3B,GAAG,cAAc,CA+CjB"}
@@ -0,0 +1,64 @@
1
+ import { createHash } from 'node:crypto';
2
+ import { canonicalize } from '../signing/canonicalize.js';
3
+ /**
4
+ * Build a verify report from manifest, policy, and violations.
5
+ */
6
+ export function buildVerifyReport(opts) {
7
+ const { manifest, policy, violations, codeledgerVersion } = opts;
8
+ // Compute policy hash using Phase 2 canonicalization
9
+ const policyForHash = {
10
+ schema_version: policy.schema_version,
11
+ mode: policy.mode,
12
+ min_confidence: policy.min_confidence,
13
+ max_drift: policy.max_drift,
14
+ require_tests: policy.require_tests,
15
+ deny_paths: policy.deny_paths,
16
+ bundle_max_files: policy.bundle_max_files,
17
+ bundle_max_bytes: policy.bundle_max_bytes,
18
+ redact_actor_identity: policy.redact_actor_identity,
19
+ store_file_paths: policy.store_file_paths,
20
+ };
21
+ const policyHash = createHash('sha256')
22
+ .update(canonicalize(policyForHash))
23
+ .digest('hex');
24
+ // Determine decision based on mode
25
+ const passed = determineDecision(policy.mode, violations);
26
+ return {
27
+ schema_version: 'mustang/verify-report/v1',
28
+ codeledger_version: codeledgerVersion,
29
+ repo: {
30
+ name: manifest.repo.name,
31
+ commit_sha: manifest.repo.commit_sha,
32
+ },
33
+ policy: {
34
+ schema_version: 'mustang/policy/v1',
35
+ mode: policy.mode,
36
+ hash: policyHash,
37
+ },
38
+ metrics: {
39
+ overall_confidence: manifest.confidence.overall,
40
+ drift_score: manifest.intent.drift_score,
41
+ bundle_file_count: manifest.bundle.file_count,
42
+ bundle_total_bytes: manifest.bundle.total_bytes,
43
+ },
44
+ decision: {
45
+ passed,
46
+ mode: policy.mode,
47
+ },
48
+ violations,
49
+ };
50
+ }
51
+ /**
52
+ * Determine pass/fail based on mode and violations.
53
+ *
54
+ * - observe: always true (violations are informational only)
55
+ * - warn: always true (violations printed as warnings)
56
+ * - block: true only if no violations
57
+ */
58
+ function determineDecision(mode, violations) {
59
+ if (mode === 'block') {
60
+ return violations.length === 0;
61
+ }
62
+ return true; // observe and warn always pass
63
+ }
64
+ //# sourceMappingURL=report.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"report.js","sourceRoot":"","sources":["../../src/verify/report.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAE1D;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAKjC;IACC,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,iBAAiB,EAAE,GAAG,IAAI,CAAC;IAEjE,qDAAqD;IACrD,MAAM,aAAa,GAA4B;QAC7C,cAAc,EAAE,MAAM,CAAC,cAAc;QACrC,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,cAAc,EAAE,MAAM,CAAC,cAAc;QACrC,SAAS,EAAE,MAAM,CAAC,SAAS;QAC3B,aAAa,EAAE,MAAM,CAAC,aAAa;QACnC,UAAU,EAAE,MAAM,CAAC,UAAU;QAC7B,gBAAgB,EAAE,MAAM,CAAC,gBAAgB;QACzC,gBAAgB,EAAE,MAAM,CAAC,gBAAgB;QACzC,qBAAqB,EAAE,MAAM,CAAC,qBAAqB;QACnD,gBAAgB,EAAE,MAAM,CAAC,gBAAgB;KAC1C,CAAC;IACF,MAAM,UAAU,GAAG,UAAU,CAAC,QAAQ,CAAC;SACpC,MAAM,CAAC,YAAY,CAAC,aAAa,CAAC,CAAC;SACnC,MAAM,CAAC,KAAK,CAAC,CAAC;IAEjB,mCAAmC;IACnC,MAAM,MAAM,GAAG,iBAAiB,CAAC,MAAM,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;IAE1D,OAAO;QACL,cAAc,EAAE,0BAA0B;QAC1C,kBAAkB,EAAE,iBAAiB;QACrC,IAAI,EAAE;YACJ,IAAI,EAAE,QAAQ,CAAC,IAAI,CAAC,IAAI;YACxB,UAAU,EAAE,QAAQ,CAAC,IAAI,CAAC,UAAU;SACrC;QACD,MAAM,EAAE;YACN,cAAc,EAAE,mBAAmB;YACnC,IAAI,EAAE,MAAM,CAAC,IAAI;YACjB,IAAI,EAAE,UAAU;SACjB;QACD,OAAO,EAAE;YACP,kBAAkB,EAAE,QAAQ,CAAC,UAAU,CAAC,OAAO;YAC/C,WAAW,EAAE,QAAQ,CAAC,MAAM,CAAC,WAAW;YACxC,iBAAiB,EAAE,QAAQ,CAAC,MAAM,CAAC,UAAU;YAC7C,kBAAkB,EAAE,QAAQ,CAAC,MAAM,CAAC,WAAW;SAChD;QACD,QAAQ,EAAE;YACR,MAAM;YACN,IAAI,EAAE,MAAM,CAAC,IAAI;SAClB;QACD,UAAU;KACX,CAAC;AACJ,CAAC;AAED;;;;;;GAMG;AACH,SAAS,iBAAiB,CAAC,IAAgB,EAAE,UAAyB;IACpE,IAAI,IAAI,KAAK,OAAO,EAAE,CAAC;QACrB,OAAO,UAAU,CAAC,MAAM,KAAK,CAAC,CAAC;IACjC,CAAC;IACD,OAAO,IAAI,CAAC,CAAC,+BAA+B;AAC9C,CAAC"}
package/package.json CHANGED
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "name": "@codeledger/cli",
3
- "version": "0.5.0",
3
+ "version": "0.6.0",
4
4
  "type": "module",
5
5
  "description": "CLI for CodeLedger — deterministic context selection for AI coding agents",
6
- "license": "Apache-2.0",
6
+ "license": "MIT",
7
7
  "repository": {
8
8
  "type": "git",
9
9
  "url": "https://github.com/codeledgerECF/codeledger-blackbox.git",
@@ -27,14 +27,14 @@
27
27
  }
28
28
  },
29
29
  "dependencies": {
30
- "@codeledger/types": "0.5.0",
31
- "@codeledger/core": "0.5.0",
32
- "@codeledger/core-engine": "0.5.0",
33
- "@codeledger/harness": "0.5.0",
34
- "@codeledger/repo": "0.5.0",
35
- "@codeledger/selector": "0.5.0",
36
- "@codeledger/instrument": "0.5.0",
37
- "@codeledger/cowork": "0.5.0"
30
+ "@codeledger/types": "0.6.0",
31
+ "@codeledger/core": "0.6.0",
32
+ "@codeledger/core-engine": "0.6.0",
33
+ "@codeledger/repo": "0.6.0",
34
+ "@codeledger/instrument": "0.6.0",
35
+ "@codeledger/harness": "0.6.0",
36
+ "@codeledger/cowork": "0.6.0",
37
+ "@codeledger/selector": "0.6.0"
38
38
  },
39
39
  "devDependencies": {
40
40
  "typescript": "^5.4.0"