@tacuchi/agent-workflow-cli 22.4.2 → 24.0.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.
- package/README.md +39 -3
- package/dist/adapters/git-cli.js +59 -17
- package/dist/adapters/git-cli.js.map +1 -1
- package/dist/adapters/node-file-system.js +55 -1
- package/dist/adapters/node-file-system.js.map +1 -1
- package/dist/adapters/postgres-readonly-tools.js +277 -0
- package/dist/adapters/postgres-readonly-tools.js.map +1 -0
- package/dist/application/artifacts-service.js +2 -2
- package/dist/application/artifacts-service.js.map +1 -1
- package/dist/application/capability/dispatcher.js +2 -2
- package/dist/application/capability/dispatcher.js.map +1 -1
- package/dist/application/capability/installed-inventory.js +2 -2
- package/dist/application/capability/installed-inventory.js.map +1 -1
- package/dist/application/capability/readiness.js +1 -1
- package/dist/application/capability/readiness.js.map +1 -1
- package/dist/application/check-branch-service.js +2 -2
- package/dist/application/check-branch-service.js.map +1 -1
- package/dist/application/checkpoint/files-touched.js +271 -0
- package/dist/application/checkpoint/files-touched.js.map +1 -0
- package/dist/application/checkpoint/markdown.js +61 -8
- package/dist/application/checkpoint/markdown.js.map +1 -1
- package/dist/application/checkpoint/state-reader.js +8 -2
- package/dist/application/checkpoint/state-reader.js.map +1 -1
- package/dist/application/checkpoint-write-service.js +16 -5
- package/dist/application/checkpoint-write-service.js.map +1 -1
- package/dist/application/claims-ledger.js +330 -0
- package/dist/application/claims-ledger.js.map +1 -0
- package/dist/application/claims-recovery.js +338 -0
- package/dist/application/claims-recovery.js.map +1 -0
- package/dist/application/database-mcp-server.js +168 -0
- package/dist/application/database-mcp-server.js.map +1 -0
- package/dist/application/database-mcp-stdio.js +137 -0
- package/dist/application/database-mcp-stdio.js.map +1 -0
- package/dist/application/database-tool-catalog.js +226 -0
- package/dist/application/database-tool-catalog.js.map +1 -0
- package/dist/application/dev-only-services.js +154 -44
- package/dist/application/dev-only-services.js.map +1 -1
- package/dist/application/dsn-reader-service.js +1 -1
- package/dist/application/elicitation-server.js +382 -0
- package/dist/application/elicitation-server.js.map +1 -0
- package/dist/application/elicitation-stdio.js +48 -0
- package/dist/application/elicitation-stdio.js.map +1 -0
- package/dist/application/flow/advance.js +86 -5
- package/dist/application/flow/advance.js.map +1 -1
- package/dist/application/flow/checkout-observation.js +152 -0
- package/dist/application/flow/checkout-observation.js.map +1 -0
- package/dist/application/flow/flow-service.js +72 -13
- package/dist/application/flow/flow-service.js.map +1 -1
- package/dist/application/flow/internal-actions.js +460 -1
- package/dist/application/flow/internal-actions.js.map +1 -1
- package/dist/application/flow/internal-drive.js +22 -9
- package/dist/application/flow/internal-drive.js.map +1 -1
- package/dist/application/flow/prove.js +205 -0
- package/dist/application/flow/prove.js.map +1 -0
- package/dist/application/flow/run-journey.js +15 -0
- package/dist/application/flow/run-journey.js.map +1 -0
- package/dist/application/flow/run-projection.js +15 -3
- package/dist/application/flow/run-projection.js.map +1 -1
- package/dist/application/flow/run-state-service.js +19 -4
- package/dist/application/flow/run-state-service.js.map +1 -1
- package/dist/application/flow/submit.js +250 -72
- package/dist/application/flow/submit.js.map +1 -1
- package/dist/application/generate-launch-service.js +4 -4
- package/dist/application/generate-launch-service.js.map +1 -1
- package/dist/application/git-flow-service.js +9 -0
- package/dist/application/git-flow-service.js.map +1 -1
- package/dist/application/local-proposal.js +9 -0
- package/dist/application/local-proposal.js.map +1 -1
- package/dist/application/lock-service.js +96 -28
- package/dist/application/lock-service.js.map +1 -1
- package/dist/application/logging/log-events.js +19 -3
- package/dist/application/logging/log-events.js.map +1 -1
- package/dist/application/logging/logger.js +2 -2
- package/dist/application/logging/logger.js.map +1 -1
- package/dist/application/mcp-connections-service.js +115 -41
- package/dist/application/mcp-connections-service.js.map +1 -1
- package/dist/application/mcp-doctor-service.js +98 -54
- package/dist/application/mcp-doctor-service.js.map +1 -1
- package/dist/application/mcp-entry-classification.js +60 -0
- package/dist/application/mcp-entry-classification.js.map +1 -0
- package/dist/application/mcp-host-reader.js +114 -81
- package/dist/application/mcp-host-reader.js.map +1 -1
- package/dist/application/mcp-host-receipt-service.js +399 -0
- package/dist/application/mcp-host-receipt-service.js.map +1 -0
- package/dist/application/mcp-host-receipt-store.js +122 -0
- package/dist/application/mcp-host-receipt-store.js.map +1 -0
- package/dist/application/mcp-host-receipts.js +28 -0
- package/dist/application/mcp-host-receipts.js.map +1 -0
- package/dist/application/mcp-host-writer.js +321 -126
- package/dist/application/mcp-host-writer.js.map +1 -1
- package/dist/application/mcp-launch-probe-service.js +142 -0
- package/dist/application/mcp-launch-probe-service.js.map +1 -0
- package/dist/application/mcp-migration-service.js +351 -0
- package/dist/application/mcp-migration-service.js.map +1 -0
- package/dist/application/mcp-native-host-check-service.js +154 -0
- package/dist/application/mcp-native-host-check-service.js.map +1 -0
- package/dist/application/mcp-receipt-registration-service.js +105 -0
- package/dist/application/mcp-receipt-registration-service.js.map +1 -0
- package/dist/application/mcp-receipt-removal-service.js +62 -0
- package/dist/application/mcp-receipt-removal-service.js.map +1 -0
- package/dist/application/mcp-remove-service.js +84 -21
- package/dist/application/mcp-remove-service.js.map +1 -1
- package/dist/application/mcp-scope-common.js +2 -4
- package/dist/application/mcp-scope-common.js.map +1 -1
- package/dist/application/mcp-setup-service.js +60 -21
- package/dist/application/mcp-setup-service.js.map +1 -1
- package/dist/application/mcp-stdio-probe.js +526 -0
- package/dist/application/mcp-stdio-probe.js.map +1 -0
- package/dist/application/mcp-test-connection-service.js +23 -50
- package/dist/application/mcp-test-connection-service.js.map +1 -1
- package/dist/application/merge-state-service.js +10 -16
- package/dist/application/merge-state-service.js.map +1 -1
- package/dist/application/multiroot/claude.js +34 -15
- package/dist/application/multiroot/claude.js.map +1 -1
- package/dist/application/multiroot/codex.js +9 -5
- package/dist/application/multiroot/codex.js.map +1 -1
- package/dist/application/multiroot-service.js +20 -11
- package/dist/application/multiroot-service.js.map +1 -1
- package/dist/application/parsers/project-block.js +25 -2
- package/dist/application/parsers/project-block.js.map +1 -1
- package/dist/application/paths-service.js +30 -31
- package/dist/application/paths-service.js.map +1 -1
- package/dist/application/plan-exec-batch-service.js +549 -0
- package/dist/application/plan-exec-batch-service.js.map +1 -0
- package/dist/application/plan-exec-decision-service.js +273 -0
- package/dist/application/plan-exec-decision-service.js.map +1 -0
- package/dist/application/project-md-service.js +2 -2
- package/dist/application/project-md-service.js.map +1 -1
- package/dist/application/project-md-upsert-service.js +4 -4
- package/dist/application/project-md-upsert-service.js.map +1 -1
- package/dist/application/project-tab-data.js +12 -7
- package/dist/application/project-tab-data.js.map +1 -1
- package/dist/application/release-data-service.js +2 -2
- package/dist/application/release-data-service.js.map +1 -1
- package/dist/application/resume-service.js +32 -11
- package/dist/application/resume-service.js.map +1 -1
- package/dist/application/retirement/apply.js +84 -0
- package/dist/application/retirement/apply.js.map +1 -1
- package/dist/application/retirement/attribution.js +31 -1
- package/dist/application/retirement/attribution.js.map +1 -1
- package/dist/application/retirement/graph.js +19 -1
- package/dist/application/retirement/graph.js.map +1 -1
- package/dist/application/retirement/journal.js +11 -0
- package/dist/application/retirement/journal.js.map +1 -1
- package/dist/application/retirement/prepare.js +89 -3
- package/dist/application/retirement/prepare.js.map +1 -1
- package/dist/application/retirement/preview.js +16 -0
- package/dist/application/retirement/preview.js.map +1 -1
- package/dist/application/retirement/resolve.js +65 -0
- package/dist/application/retirement/resolve.js.map +1 -1
- package/dist/application/self/host-states.js +2 -0
- package/dist/application/self/host-states.js.map +1 -1
- package/dist/application/self/install-skill.js +21 -17
- package/dist/application/self/install-skill.js.map +1 -1
- package/dist/application/self/mcp-config.js +392 -84
- package/dist/application/self/mcp-config.js.map +1 -1
- package/dist/application/self/mcp-via-state.js +62 -0
- package/dist/application/self/mcp-via-state.js.map +1 -0
- package/dist/application/self/uninstall.js +15 -5
- package/dist/application/self/uninstall.js.map +1 -1
- package/dist/application/session-close-service.js +24 -1
- package/dist/application/session-close-service.js.map +1 -1
- package/dist/application/session-create-service.js +7 -0
- package/dist/application/session-create-service.js.map +1 -1
- package/dist/application/session-resume-service.js +2 -2
- package/dist/application/session-resume-service.js.map +1 -1
- package/dist/application/sessions-service.js +2 -4
- package/dist/application/sessions-service.js.map +1 -1
- package/dist/application/skills-resolver-service.js +4 -4
- package/dist/application/skills-resolver-service.js.map +1 -1
- package/dist/application/source-boundary-policy.js +18 -7
- package/dist/application/source-boundary-policy.js.map +1 -1
- package/dist/application/source-remove-service.js +12 -1
- package/dist/application/source-remove-service.js.map +1 -1
- package/dist/application/sources-service.js +2 -2
- package/dist/application/sources-service.js.map +1 -1
- package/dist/application/status-service.js +4 -0
- package/dist/application/status-service.js.map +1 -1
- package/dist/application/visibility-doctor-service.js +1 -1
- package/dist/application/visibility-doctor-service.js.map +1 -1
- package/dist/application/workline-index-service.js +182 -27
- package/dist/application/workline-index-service.js.map +1 -1
- package/dist/application/workspace-init-service.js +89 -271
- package/dist/application/workspace-init-service.js.map +1 -1
- package/dist/application/workspace-materialization-service.js +300 -0
- package/dist/application/workspace-materialization-service.js.map +1 -0
- package/dist/application/worktree-service.js +32 -3
- package/dist/application/worktree-service.js.map +1 -1
- package/dist/cli/commands/capability.js +4 -7
- package/dist/cli/commands/capability.js.map +1 -1
- package/dist/cli/commands/claims.js +72 -0
- package/dist/cli/commands/claims.js.map +1 -0
- package/dist/cli/commands/dev-only.js +73 -25
- package/dist/cli/commands/dev-only.js.map +1 -1
- package/dist/cli/commands/flow.js +145 -42
- package/dist/cli/commands/flow.js.map +1 -1
- package/dist/cli/commands/index.js +4 -0
- package/dist/cli/commands/index.js.map +1 -1
- package/dist/cli/commands/mcp.js +752 -76
- package/dist/cli/commands/mcp.js.map +1 -1
- package/dist/cli/commands/multiroot.js +40 -7
- package/dist/cli/commands/multiroot.js.map +1 -1
- package/dist/cli/commands/resume.js +9 -3
- package/dist/cli/commands/resume.js.map +1 -1
- package/dist/cli/commands/retirement.js +9 -0
- package/dist/cli/commands/retirement.js.map +1 -1
- package/dist/cli/commands/session-create.js +1 -1
- package/dist/cli/commands/session-create.js.map +1 -1
- package/dist/cli/commands/skills.js +1 -1
- package/dist/cli/commands/skills.js.map +1 -1
- package/dist/cli/commands/status.js +72 -24
- package/dist/cli/commands/status.js.map +1 -1
- package/dist/cli/commands/tool.js +141 -0
- package/dist/cli/commands/tool.js.map +1 -0
- package/dist/cli/commands/workspace-init.js +5 -5
- package/dist/cli/commands/workspace-init.js.map +1 -1
- package/dist/cli/help-groups.js +6 -1
- package/dist/cli/help-groups.js.map +1 -1
- package/dist/cli/main.js +272 -67
- package/dist/cli/main.js.map +1 -1
- package/dist/cli/parser.js +8 -1
- package/dist/cli/parser.js.map +1 -1
- package/dist/cli/registry.js.map +1 -1
- package/dist/cli/render.js +15 -2
- package/dist/cli/render.js.map +1 -1
- package/dist/cli/tui/app.js +3 -2
- package/dist/cli/tui/app.js.map +1 -1
- package/dist/cli/tui/components/workspace-init-form.js +7 -7
- package/dist/cli/tui/components/workspace-init-form.js.map +1 -1
- package/dist/cli/tui/data/workflow-content.js +2 -2
- package/dist/cli/tui/data/workflow-content.js.map +1 -1
- package/dist/cli/tui/tabs/config-tab.js +4 -3
- package/dist/cli/tui/tabs/config-tab.js.map +1 -1
- package/dist/cli/tui/tabs/mcp-tab-helpers.js +72 -1
- package/dist/cli/tui/tabs/mcp-tab-helpers.js.map +1 -1
- package/dist/cli/tui/tabs/mcp-tab.js +101 -42
- package/dist/cli/tui/tabs/mcp-tab.js.map +1 -1
- package/dist/cli/tui/tabs/project-tab.js +18 -21
- package/dist/cli/tui/tabs/project-tab.js.map +1 -1
- package/dist/cli/tui/workspace-root.js +13 -0
- package/dist/cli/tui/workspace-root.js.map +1 -0
- package/dist/domain/capability/protocol.js +2 -2
- package/dist/domain/capability/protocol.js.map +1 -1
- package/dist/domain/database-tools.js +445 -0
- package/dist/domain/database-tools.js.map +1 -0
- package/dist/domain/degradation-notice.js +60 -0
- package/dist/domain/degradation-notice.js.map +1 -0
- package/dist/domain/elicitation.js +152 -0
- package/dist/domain/elicitation.js.map +1 -0
- package/dist/domain/flow/answer.js +173 -42
- package/dist/domain/flow/answer.js.map +1 -1
- package/dist/domain/flow/authority.js +184 -127
- package/dist/domain/flow/authority.js.map +1 -1
- package/dist/domain/flow/directive.js +47 -1
- package/dist/domain/flow/directive.js.map +1 -1
- package/dist/domain/flow/rules.js +7 -4
- package/dist/domain/flow/rules.js.map +1 -1
- package/dist/domain/flow/run-state.js +636 -31
- package/dist/domain/flow/run-state.js.map +1 -1
- package/dist/domain/harnesses.js +16 -0
- package/dist/domain/harnesses.js.map +1 -1
- package/dist/domain/mcp-entry.js +164 -28
- package/dist/domain/mcp-entry.js.map +1 -1
- package/dist/domain/postgres-object-search.js +320 -0
- package/dist/domain/postgres-object-search.js.map +1 -0
- package/dist/domain/redaction.js +47 -0
- package/dist/domain/redaction.js.map +1 -0
- package/dist/domain/retirement/proposal.js +1 -0
- package/dist/domain/retirement/proposal.js.map +1 -1
- package/dist/domain/structured-choice-stamp.js +32 -4
- package/dist/domain/structured-choice-stamp.js.map +1 -1
- package/dist/domain/workline-mcp-entry.js +34 -0
- package/dist/domain/workline-mcp-entry.js.map +1 -0
- package/dist/ports/postgres-tools.js +10 -0
- package/dist/ports/postgres-tools.js.map +1 -0
- package/dist/runtime/namespace-resolver.js +104 -18
- package/dist/runtime/namespace-resolver.js.map +1 -1
- package/package.json +5 -1
- package/skills/w/README.md +2 -2
- package/skills/w/SKILL.md +9 -10
- package/skills/w/artifacts/README.md +1 -1
- package/skills/w/commands/README.md +3 -3
- package/skills/w/commands/persist.md +3 -1
- package/skills/w/commands/resume.md +1 -1
- package/skills/w/commands/spec-new.md +2 -2
- package/skills/w/commands/status.md +1 -1
- package/skills/w/commands/workspace-init.md +9 -10
- package/skills/w/context/MANIFEST.json +1 -4
- package/skills/w/harness/HARNESS.md +1 -1
- package/skills/w/loops/quick-loop/LOOP.md +1 -1
- package/skills/w/modules/PROMPT-CONTINUITY.md +1 -1
- package/skills/w/modules/WORKSPACE-SCAFFOLD.md +17 -20
- package/skills/w/schemas/capability-descriptor.schema.json +1 -1
- package/dist/application/mcp-dbhub-launcher.js +0 -216
- package/dist/application/mcp-dbhub-launcher.js.map +0 -1
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { createHash } from "node:crypto";
|
|
2
|
+
import { CONTEXTUAL_LIMIT, WORKSPACE_UNIT, } from "./files-touched.js";
|
|
2
3
|
/**
|
|
3
4
|
* The trailing seal: a digest of the very bytes this module emitted.
|
|
4
5
|
*
|
|
@@ -60,20 +61,72 @@ function appendDecisions(lines, state) {
|
|
|
60
61
|
lines.push("_No decisions recorded._");
|
|
61
62
|
}
|
|
62
63
|
}
|
|
64
|
+
/**
|
|
65
|
+
* The heading no longer says "post-last-commit".
|
|
66
|
+
*
|
|
67
|
+
* It promised a window this section never delivered — the inventory is the
|
|
68
|
+
* CURRENT state of the tree, and reading it as "what changed since the last
|
|
69
|
+
* commit of this session" is what made an operator distrust it. The reference
|
|
70
|
+
* each unit is actually compared against is now stated in the section itself,
|
|
71
|
+
* which is both honest and more useful than a label in the heading. The former
|
|
72
|
+
* headings stay readable: they are kept as aliases in the heading table.
|
|
73
|
+
*/
|
|
63
74
|
function appendFilesTouched(lines, state) {
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
75
|
+
const touched = state.files_touched;
|
|
76
|
+
lines.push("", "## Files touched", "");
|
|
77
|
+
lines.push(scopeLine(touched), "");
|
|
78
|
+
for (const unit of touched.unobserved) {
|
|
79
|
+
lines.push(`- **Not observed — ${unit.alias}** at \`${unit.boundary}\`: ${unit.reason}`);
|
|
80
|
+
}
|
|
81
|
+
if (touched.unobserved.length > 0)
|
|
82
|
+
lines.push("");
|
|
83
|
+
// Claimed paths first: the readable cap applies to the rest, so nothing the
|
|
84
|
+
// session actually produced can be pushed out of sight by unrelated noise.
|
|
85
|
+
const shown = [...touched.linked, ...touched.contextual];
|
|
86
|
+
if (shown.length === 0) {
|
|
87
|
+
// "Nothing changed" is only sayable when something was read. A collection
|
|
88
|
+
// that failed is declared above and must never be spelled as a clean tree.
|
|
89
|
+
lines.push(touched.observed.length === 0
|
|
90
|
+
? "_No unit in scope could be read — see the declaration above._"
|
|
91
|
+
: "_No uncommitted changes inside the scope above._");
|
|
68
92
|
return;
|
|
69
93
|
}
|
|
70
|
-
for (const
|
|
71
|
-
lines.push(`- ${
|
|
94
|
+
for (const file of shown) {
|
|
95
|
+
lines.push(`- ${labelOf(file)}${countsOf(file)} — _[AI: purpose in 1 line]_`);
|
|
72
96
|
}
|
|
73
|
-
if (
|
|
74
|
-
|
|
97
|
+
if (touched.omitted.length > 0) {
|
|
98
|
+
// Named by unit, not merely counted: "30 more" over two units reads as if
|
|
99
|
+
// both were shown, and a reader has no way to tell which one was cut.
|
|
100
|
+
const total = touched.omitted.reduce((sum, entry) => sum + entry.count, 0);
|
|
101
|
+
const noun = total === 1 ? "change" : "changes";
|
|
102
|
+
const perUnit = touched.omitted.map((entry) => `${entry.unit} ${entry.count}`).join(", ");
|
|
103
|
+
lines.push(`- _… and ${total} more contextual ${noun} not listed (cap ${CONTEXTUAL_LIMIT}): ${perUnit}_`);
|
|
75
104
|
}
|
|
76
105
|
}
|
|
106
|
+
/** States the boundary and the reference, so the inventory explains itself. */
|
|
107
|
+
function scopeLine(touched) {
|
|
108
|
+
if (touched.observed.length === 0) {
|
|
109
|
+
return "_Scope: no unit could be read. What this section reports is the current working-tree state, never a window over the session._";
|
|
110
|
+
}
|
|
111
|
+
const units = touched.observed.map((unit) => {
|
|
112
|
+
const reference = unit.reference === null ? "no commit yet" : `vs ${unit.reference.slice(0, 7)}`;
|
|
113
|
+
return `${unit.alias} at \`${unit.boundary}\` (${reference})`;
|
|
114
|
+
});
|
|
115
|
+
return `_Scope: ${units.join("; ")}. Current working-tree state, untracked files included — not a window over the session._`;
|
|
116
|
+
}
|
|
117
|
+
/** A path from another unit is spelled with its alias: two units can share one. */
|
|
118
|
+
function labelOf(file) {
|
|
119
|
+
return file.unit === WORKSPACE_UNIT ? file.path : `${file.unit}:${file.path}`;
|
|
120
|
+
}
|
|
121
|
+
function countsOf(file) {
|
|
122
|
+
if (file.added === null || file.removed === null)
|
|
123
|
+
return "";
|
|
124
|
+
// git spells a binary file's deltas as `-`, and `(+- --)` reads like a
|
|
125
|
+
// rendering bug rather than like "this file has no line count".
|
|
126
|
+
if (file.added === "-" || file.removed === "-")
|
|
127
|
+
return " (binary)";
|
|
128
|
+
return ` (+${file.added} -${file.removed})`;
|
|
129
|
+
}
|
|
77
130
|
function appendContext(lines) {
|
|
78
131
|
lines.push("", "## Critical context to resume", "");
|
|
79
132
|
lines.push("_[AI: 2-3 paragraphs with the minimum info needed to continue without re-exploring. What was discovered, what decisions are settled, what to keep in mind.]_");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"markdown.js","sourceRoot":"","sources":["../../../src/application/checkpoint/markdown.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"markdown.js","sourceRoot":"","sources":["../../../src/application/checkpoint/markdown.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EACL,gBAAgB,EAGhB,cAAc,GACf,MAAM,oBAAoB,CAAC;AAG5B;;;;;;;;;;;;GAYG;AACH,MAAM,OAAO,GACX,+FAA+F,CAAC;AAElG,MAAM,UAAU,kBAAkB,CAAC,KAAmB;IACpD,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,YAAY,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;IAC3B,eAAe,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;IAC9B,kBAAkB,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;IACjC,aAAa,CAAC,KAAK,CAAC,CAAC;IACrB,UAAU,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;IACzB,4EAA4E;IAC5E,qCAAqC;IACrC,MAAM,IAAI,GAAG,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC;IACvC,OAAO,GAAG,IAAI,gDAAgD,KAAK,CAAC,SAAS,sBAAsB,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC;AAC5H,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,oBAAoB,CAAC,IAAY;IAC/C,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAClC,MAAM,MAAM,GAAG,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC;IAC1B,IAAI,MAAM,KAAK,SAAS,IAAI,KAAK,EAAE,KAAK,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC;IACrE,OAAO,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,KAAK,MAAM,CAAC;AACzD,CAAC;AAED,SAAS,QAAQ,CAAC,IAAY;IAC5B,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AACjE,CAAC;AAED,SAAS,YAAY,CAAC,KAAe,EAAE,KAAmB;IACxD,MAAM,QAAQ,GAAG,KAAK,CAAC,YAAY,CAAC;IACpC,MAAM,YAAY,GAChB,QAAQ,KAAK,IAAI;QACf,CAAC,CAAC,GAAG,QAAQ,MAAM,KAAK,CAAC,KAAK,CAAC,MAAM,OAAO,KAAK,CAAC,KAAK,CAAC,KAAK,kBAAkB;QAC/E,CAAC,CAAC,gDAAgD,CAAC;IACvD,KAAK,CAAC,IAAI,CACR,kBAAkB,KAAK,CAAC,MAAM,EAAE,EAChC,EAAE,EACF,cAAc,KAAK,CAAC,SAAS,EAAE,EAC/B,eAAe,YAAY,EAAE,EAC7B,EAAE,EACF,gBAAgB,EAChB,EAAE,EACF,gHAAgH,EAChH,EAAE,EACF,cAAc,EACd,EAAE,EACF,gFAAgF,EAChF,EAAE,CACH,CAAC;AACJ,CAAC;AAED,SAAS,eAAe,CAAC,KAAe,EAAE,KAAmB;IAC3D,KAAK,CAAC,IAAI,CAAC,qBAAqB,EAAE,EAAE,CAAC,CAAC;IACtC,IAAI,KAAK,CAAC,aAAa,EAAE,CAAC;QACxB,KAAK,CAAC,IAAI,CAAC,KAAK,KAAK,CAAC,aAAa,CAAC,EAAE,KAAK,KAAK,CAAC,aAAa,CAAC,OAAO,EAAE,CAAC,CAAC;IAC5E,CAAC;SAAM,CAAC;QACN,KAAK,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAC;IACzC,CAAC;AACH,CAAC;AAED;;;;;;;;;GASG;AACH,SAAS,kBAAkB,CAAC,KAAe,EAAE,KAAmB;IAC9D,MAAM,OAAO,GAAG,KAAK,CAAC,aAAa,CAAC;IACpC,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,kBAAkB,EAAE,EAAE,CAAC,CAAC;IACvC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,EAAE,CAAC,CAAC;IACnC,KAAK,MAAM,IAAI,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC;QACtC,KAAK,CAAC,IAAI,CAAC,sBAAsB,IAAI,CAAC,KAAK,WAAW,IAAI,CAAC,QAAQ,OAAO,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;IAC3F,CAAC;IACD,IAAI,OAAO,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC;QAAE,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAElD,4EAA4E;IAC5E,2EAA2E;IAC3E,MAAM,KAAK,GAAG,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IACzD,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,0EAA0E;QAC1E,2EAA2E;QAC3E,KAAK,CAAC,IAAI,CACR,OAAO,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC;YAC3B,CAAC,CAAC,+DAA+D;YACjE,CAAC,CAAC,kDAAkD,CACvD,CAAC;QACF,OAAO;IACT,CAAC;IACD,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,KAAK,CAAC,IAAI,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,QAAQ,CAAC,IAAI,CAAC,8BAA8B,CAAC,CAAC;IAChF,CAAC;IACD,IAAI,OAAO,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC/B,0EAA0E;QAC1E,sEAAsE;QACtE,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE,CAAC,GAAG,GAAG,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;QAC3E,MAAM,IAAI,GAAG,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC;QAChD,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,GAAG,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC1F,KAAK,CAAC,IAAI,CACR,YAAY,KAAK,oBAAoB,IAAI,oBAAoB,gBAAgB,MAAM,OAAO,GAAG,CAC9F,CAAC;IACJ,CAAC;AACH,CAAC;AAED,+EAA+E;AAC/E,SAAS,SAAS,CAAC,OAAqB;IACtC,IAAI,OAAO,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAClC,OAAO,+HAA+H,CAAC;IACzI,CAAC;IACD,MAAM,KAAK,GAAG,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;QAC1C,MAAM,SAAS,GACb,IAAI,CAAC,SAAS,KAAK,IAAI,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;QACjF,OAAO,GAAG,IAAI,CAAC,KAAK,SAAS,IAAI,CAAC,QAAQ,OAAO,SAAS,GAAG,CAAC;IAChE,CAAC,CAAC,CAAC;IACH,OAAO,WAAW,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,0FAA0F,CAAC;AAC/H,CAAC;AAED,mFAAmF;AACnF,SAAS,OAAO,CAAC,IAAiB;IAChC,OAAO,IAAI,CAAC,IAAI,KAAK,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;AAChF,CAAC;AAED,SAAS,QAAQ,CAAC,IAAiB;IACjC,IAAI,IAAI,CAAC,KAAK,KAAK,IAAI,IAAI,IAAI,CAAC,OAAO,KAAK,IAAI;QAAE,OAAO,EAAE,CAAC;IAC5D,uEAAuE;IACvE,gEAAgE;IAChE,IAAI,IAAI,CAAC,KAAK,KAAK,GAAG,IAAI,IAAI,CAAC,OAAO,KAAK,GAAG;QAAE,OAAO,WAAW,CAAC;IACnE,OAAO,MAAM,IAAI,CAAC,KAAK,KAAK,IAAI,CAAC,OAAO,GAAG,CAAC;AAC9C,CAAC;AAED,SAAS,aAAa,CAAC,KAAe;IACpC,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,+BAA+B,EAAE,EAAE,CAAC,CAAC;IACpD,KAAK,CAAC,IAAI,CACR,8JAA8J,CAC/J,CAAC;AACJ,CAAC;AAED,SAAS,UAAU,CAAC,KAAe,EAAE,KAAmB;IACtD,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,EAAE,CAAC,CAAC;IAC9B,IAAI,KAAK,CAAC,MAAM;QAAE,KAAK,CAAC,IAAI,CAAC,aAAa,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;IAC1D,MAAM,OAAO,GAAG,gBAAgB,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;IAClD,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACvB,KAAK,CAAC,IAAI,CAAC,wBAAwB,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC3D,CAAC;IACD,KAAK,CAAC,IAAI,CAAC,mEAAmE,CAAC,CAAC;AAClF,CAAC;AAED,SAAS,gBAAgB,CAAC,SAA2C;IACnE,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC;QAC/C,IAAI,CAAC,KAAK,eAAe;YAAE,SAAS;QACpC,IAAI,CAAC,KAAK,IAAI;YAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClC,CAAC;IACD,MAAM,YAAY,GAAG,SAAS,CAAC,aAAa,CAAC;IAC7C,IAAI,OAAO,YAAY,KAAK,QAAQ,IAAI,YAAY,GAAG,CAAC,EAAE,CAAC;QACzD,OAAO,CAAC,IAAI,CAAC,WAAW,YAAY,GAAG,CAAC,CAAC;IAC3C,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC"}
|
|
@@ -1,13 +1,19 @@
|
|
|
1
1
|
import { join } from "node:path";
|
|
2
2
|
import { localMinuteIso } from "../dates.js";
|
|
3
3
|
import { findArtifact, listExistingArtifacts } from "../session-artifacts.js";
|
|
4
|
-
|
|
4
|
+
import { collectFilesTouched } from "./files-touched.js";
|
|
5
|
+
/**
|
|
6
|
+
* `workspaceRoot` and not the process's cwd on purpose: the cwd is wherever the
|
|
7
|
+
* operator happened to stand, and using it made the inventory's boundary an
|
|
8
|
+
* accident of invocation instead of a property of the session.
|
|
9
|
+
*/
|
|
10
|
+
export async function extractSessionState(fs, git, workspaceRoot, sessionPath) {
|
|
5
11
|
const folder = sessionPath.split(/[\\/]/).pop() ?? "";
|
|
6
12
|
const tasks = await countTasks(fs, sessionPath);
|
|
7
13
|
const progressPct = tasks.total > 0 ? Math.round((100 * tasks.closed) / tasks.total) : null;
|
|
8
14
|
const lastDecision = await readLastDecision(fs, sessionPath);
|
|
9
15
|
const artefacts = await listArtefacts(fs, sessionPath);
|
|
10
|
-
const filesTouched = await git
|
|
16
|
+
const filesTouched = await collectFilesTouched(fs, git, workspaceRoot, sessionPath);
|
|
11
17
|
const origen = await readOrigen(fs, sessionPath);
|
|
12
18
|
return {
|
|
13
19
|
folder,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"state-reader.js","sourceRoot":"","sources":["../../../src/application/checkpoint/state-reader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAGjC,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"state-reader.js","sourceRoot":"","sources":["../../../src/application/checkpoint/state-reader.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { join } from "node:path";
|
|
2
2
|
import { findActiveSessions } from "./checkpoint-service.js";
|
|
3
|
+
import { totalInScope } from "./checkpoint/files-touched.js";
|
|
3
4
|
import { formatCheckpointMd, isPristineCheckpoint } from "./checkpoint/markdown.js";
|
|
4
5
|
import { extractSessionState } from "./checkpoint/state-reader.js";
|
|
5
6
|
import { resolveLifecycleTarget, unresolvedDetail, } from "./lifecycle-target.js";
|
|
7
|
+
import { resolveWorkspaceRoot } from "./paths-service.js";
|
|
6
8
|
import { writeSessionNarrative } from "./session-narrative.js";
|
|
7
9
|
// This module deliberately owns NO placeholder marker of its own. `_[AI:` used
|
|
8
10
|
// to be declared here as well as in `checkpoint-service.ts`, with incompatible
|
|
@@ -37,7 +39,15 @@ export async function runCheckpointWrite(fs, env, git, paths, options = {}) {
|
|
|
37
39
|
reason: PRESERVED_REASON,
|
|
38
40
|
};
|
|
39
41
|
}
|
|
40
|
-
|
|
42
|
+
// The workspace root rather than the raw cwd. Today the two coincide by
|
|
43
|
+
// construction — session resolution already refuses to run from a
|
|
44
|
+
// subdirectory, so nothing reaches here with a deeper cwd — and what actually
|
|
45
|
+
// bounds the reading is `repoPrefix` inside the collection. This stays the
|
|
46
|
+
// resolved root anyway: it is the value the boundary is DEFINED as, so the
|
|
47
|
+
// day session resolution learns to walk up, the inventory does not silently
|
|
48
|
+
// widen to the parent repository along with it.
|
|
49
|
+
const workspaceRoot = await resolveWorkspaceRoot(fs, env, paths);
|
|
50
|
+
const state = await extractSessionState(fs, git, workspaceRoot, session.path);
|
|
41
51
|
const md = formatCheckpointMd(state);
|
|
42
52
|
await fs.mkdirp(session.path);
|
|
43
53
|
await fs.writeText(cpPath, md);
|
|
@@ -52,7 +62,7 @@ export async function runCheckpointWrite(fs, env, git, paths, options = {}) {
|
|
|
52
62
|
progress_pct: state.progress_pct,
|
|
53
63
|
tasks_open: state.tasks.open,
|
|
54
64
|
tasks_closed: state.tasks.closed,
|
|
55
|
-
files_touched_count: state.files_touched
|
|
65
|
+
files_touched_count: totalInScope(state.files_touched),
|
|
56
66
|
};
|
|
57
67
|
}
|
|
58
68
|
/**
|
|
@@ -78,10 +88,11 @@ export async function runAutoCompactOnClose(fs, env, git, paths, options = {}) {
|
|
|
78
88
|
action: detail.action,
|
|
79
89
|
};
|
|
80
90
|
}
|
|
81
|
-
const
|
|
91
|
+
const workspaceRoot = await resolveWorkspaceRoot(fs, env, paths);
|
|
92
|
+
const entry = await writeCheckpointForTarget(fs, git, workspaceRoot, target.session);
|
|
82
93
|
return { checkpoints_written: [entry] };
|
|
83
94
|
}
|
|
84
|
-
async function writeCheckpointForTarget(fs, git,
|
|
95
|
+
async function writeCheckpointForTarget(fs, git, workspaceRoot, session) {
|
|
85
96
|
const cpPath = join(session.path, "CHECKPOINT.md");
|
|
86
97
|
// No `force` here on purpose: SessionEnd is a hook, and a hook is never the
|
|
87
98
|
// declared intention that AC-02 asks for before overwriting content.
|
|
@@ -95,7 +106,7 @@ async function writeCheckpointForTarget(fs, git, cwd, session) {
|
|
|
95
106
|
};
|
|
96
107
|
}
|
|
97
108
|
try {
|
|
98
|
-
const state = await extractSessionState(fs, git,
|
|
109
|
+
const state = await extractSessionState(fs, git, workspaceRoot, session.path);
|
|
99
110
|
const md = formatCheckpointMd(state);
|
|
100
111
|
await fs.mkdirp(session.path);
|
|
101
112
|
await fs.writeText(cpPath, md);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"checkpoint-write-service.js","sourceRoot":"","sources":["../../src/application/checkpoint-write-service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAIjC,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AACpF,OAAO,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AACnE,OAAO,EAGL,sBAAsB,EACtB,gBAAgB,GACjB,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"checkpoint-write-service.js","sourceRoot":"","sources":["../../src/application/checkpoint-write-service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAIjC,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAC7D,OAAO,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AACpF,OAAO,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AACnE,OAAO,EAGL,sBAAsB,EACtB,gBAAgB,GACjB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAqB,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAC7E,OAAO,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAG/D,+EAA+E;AAC/E,+EAA+E;AAC/E,8EAA8E;AAC9E,gFAAgF;AAChF,wEAAwE;AACxE,6EAA6E;AAC7E,+BAA+B;AAE/B,iFAAiF;AACjF,MAAM,gBAAgB,GACpB,qFAAqF,CAAC;AA+CxF;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,EAAkB,EAClB,GAAY,EACZ,GAAY,EACZ,KAAmB,EACnB,UAAkC,EAAE;IAEpC,6EAA6E;IAC7E,6EAA6E;IAC7E,2CAA2C;IAC3C,MAAM,MAAM,GAAG,MAAM,sBAAsB,CAAC,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;IACxE,IAAI,MAAM,CAAC,OAAO,KAAK,UAAU;QAAE,OAAO,UAAU,CAAC,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IACxE,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC;IAC/B,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,eAAe,CAAC,CAAC;IAEnD,IAAI,MAAM,oBAAoB,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,KAAK,KAAK,IAAI,CAAC,EAAE,CAAC;QACnE,OAAO;YACL,OAAO,EAAE,OAAO,CAAC,MAAM;YACvB,eAAe,EAAE,MAAM;YACvB,OAAO,EAAE,IAAI;YACb,SAAS,EAAE,IAAI;YACf,MAAM,EAAE,gBAAgB;SACzB,CAAC;IACJ,CAAC;IAED,wEAAwE;IACxE,kEAAkE;IAClE,8EAA8E;IAC9E,2EAA2E;IAC3E,2EAA2E;IAC3E,4EAA4E;IAC5E,gDAAgD;IAChD,MAAM,aAAa,GAAG,MAAM,oBAAoB,CAAC,EAAE,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC;IACjE,MAAM,KAAK,GAAG,MAAM,mBAAmB,CAAC,EAAE,EAAE,GAAG,EAAE,aAAa,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9E,MAAM,EAAE,GAAG,kBAAkB,CAAC,KAAK,CAAC,CAAC;IACrC,MAAM,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9B,MAAM,EAAE,CAAC,SAAS,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IAC/B,6EAA6E;IAC7E,2EAA2E;IAC3E,6EAA6E;IAC7E,MAAM,qBAAqB,CAAC,EAAE,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;IAEvF,OAAO;QACL,OAAO,EAAE,OAAO,CAAC,MAAM;QACvB,eAAe,EAAE,MAAM;QACvB,aAAa,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM;QACvD,YAAY,EAAE,KAAK,CAAC,YAAY;QAChC,UAAU,EAAE,KAAK,CAAC,KAAK,CAAC,IAAI;QAC5B,YAAY,EAAE,KAAK,CAAC,KAAK,CAAC,MAAM;QAChC,mBAAmB,EAAE,YAAY,CAAC,KAAK,CAAC,aAAa,CAAC;KACvD,CAAC;AACJ,CAAC;AAmBD;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,EAAkB,EAClB,GAAY,EACZ,GAAY,EACZ,KAAmB,EACnB,UAA4B,EAAE;IAE9B,oEAAoE;IACpE,6EAA6E;IAC7E,sEAAsE;IACtE,0CAA0C;IAC1C,MAAM,MAAM,GAAG,MAAM,sBAAsB,CACzC,EAAE,EACF,KAAK,EACL,EAAE,GAAG,OAAO,EAAE,kBAAkB,EAAE,KAAK,EAAE,EACzC,WAAW,CACZ,CAAC;IACF,IAAI,MAAM,CAAC,OAAO,KAAK,UAAU,EAAE,CAAC;QAClC,MAAM,MAAM,GAAG,gBAAgB,CAAC,MAAM,CAAC,CAAC;QACxC,OAAO;YACL,mBAAmB,EAAE,EAAE;YACvB,UAAU,EAAE,UAAU;YACtB,eAAe,EAAE,IAAI;YACrB,UAAU,EAAE,MAAM,CAAC,UAAU;YAC7B,MAAM,EAAE,MAAM,CAAC,MAAM;SACtB,CAAC;IACJ,CAAC;IACD,MAAM,aAAa,GAAG,MAAM,oBAAoB,CAAC,EAAE,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC;IACjE,MAAM,KAAK,GAAG,MAAM,wBAAwB,CAAC,EAAE,EAAE,GAAG,EAAE,aAAa,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;IACrF,OAAO,EAAE,mBAAmB,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC;AAC1C,CAAC;AAED,KAAK,UAAU,wBAAwB,CACrC,EAAkB,EAClB,GAAY,EACZ,aAAqB,EACrB,OAAqB;IAErB,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,eAAe,CAAC,CAAC;IACnD,4EAA4E;IAC5E,qEAAqE;IACrE,IAAI,MAAM,oBAAoB,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,CAAC;QAClD,OAAO;YACL,OAAO,EAAE,OAAO,CAAC,MAAM;YACvB,eAAe,EAAE,MAAM;YACvB,OAAO,EAAE,IAAI;YACb,SAAS,EAAE,IAAI;YACf,MAAM,EAAE,gBAAgB;SACzB,CAAC;IACJ,CAAC;IACD,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,MAAM,mBAAmB,CAAC,EAAE,EAAE,GAAG,EAAE,aAAa,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;QAC9E,MAAM,EAAE,GAAG,kBAAkB,CAAC,KAAK,CAAC,CAAC;QACrC,MAAM,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAC9B,MAAM,EAAE,CAAC,SAAS,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QAC/B,OAAO;YACL,OAAO,EAAE,OAAO,CAAC,MAAM;YACvB,eAAe,EAAE,MAAM;YACvB,YAAY,EAAE,KAAK,CAAC,YAAY;SACjC,CAAC;IACJ,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO;YACL,OAAO,EAAE,OAAO,CAAC,MAAM;YACvB,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,IAAI,KAAK,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;SAC1E,CAAC;IACJ,CAAC;AACH,CAAC;AAED;;;;;;;GAOG;AACH,KAAK,UAAU,oBAAoB,CACjC,EAAkB,EAClB,MAAc,EACd,KAAc;IAEd,IAAI,KAAK;QAAE,OAAO,KAAK,CAAC;IACxB,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAAE,OAAO,KAAK,CAAC;IAC7C,OAAO,CAAC,oBAAoB,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;AAC1D,CAAC;AAED,KAAK,UAAU,UAAU,CACvB,EAAkB,EAClB,KAAmB,EACnB,MAAqE;IAErE,IAAI,MAAM,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;QACjC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,YAAY,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC;IACjF,CAAC;IACD,MAAM,OAAO,GAAG,MAAM,kBAAkB,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;IACpD,OAAO;QACL,OAAO,EAAE,IAAI;QACb,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,UAAU,EAAE,UAAU;QACtB,eAAe,EAAE,IAAI;QACrB,eAAe,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC;QAC7C,UAAU,EAAE,MAAM,CAAC,UAAU;QAC7B,MAAM,EAAE,MAAM,CAAC,MAAM;KACtB,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,330 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The durable trace of a reservation's whole life — and the only place it lives.
|
|
3
|
+
*
|
|
4
|
+
* A claim used to leave exactly one artifact: the marker file itself. That made
|
|
5
|
+
* the reservation visible while it existed and completely unaccountable once it
|
|
6
|
+
* did not. Nothing recorded who had claimed a correlative, why it went away, or
|
|
7
|
+
* whether it had ever been published — so a released number was
|
|
8
|
+
* indistinguishable from one that never existed, and a recovery had no evidence
|
|
9
|
+
* to stand on.
|
|
10
|
+
*
|
|
11
|
+
* This ledger is append-only and lives under `.workflow/`, deliberately OUTSIDE
|
|
12
|
+
* `docs/`: the corpus is for documents somebody published, and a reservation's
|
|
13
|
+
* history is not one. Putting it in `docs/` would make the trace itself look like
|
|
14
|
+
* a spec or a plan, which is the confusion the whole change exists to end.
|
|
15
|
+
*
|
|
16
|
+
* It answers three different questions with one file, which is why there is one
|
|
17
|
+
* file and not three:
|
|
18
|
+
* - **what happened** — the audit trail, still readable after the session's
|
|
19
|
+
* folder is gone, because a session is deleted and its history should not be;
|
|
20
|
+
* - **which correlatives came back** — a number released and never published is
|
|
21
|
+
* eligible again, and only this record knows the difference;
|
|
22
|
+
* - **what may no longer be published** — a revocation is a durable fence, and
|
|
23
|
+
* a fence that lives in memory is not one.
|
|
24
|
+
*
|
|
25
|
+
* Append-only is load-bearing for the third: a record that can be rewritten is a
|
|
26
|
+
* fence somebody can lift, and the revocation has to be irrevocable to be worth
|
|
27
|
+
* anything.
|
|
28
|
+
*/
|
|
29
|
+
import { join } from "node:path";
|
|
30
|
+
import { compareCorrelatives, isCorrelative } from "../domain/correlative.js";
|
|
31
|
+
/** Lives next to HISTORY.md: workspace state, never workspace corpus. */
|
|
32
|
+
const LEDGER_FILE = "claims.jsonl";
|
|
33
|
+
const LEDGER_VERSION = 1;
|
|
34
|
+
/** The identity as one comparable string. Order is fixed so it is stable. */
|
|
35
|
+
export function claimKey(claim) {
|
|
36
|
+
return `${claim.category}/${claim.correlative}-${claim.name}@${claim.owner}`;
|
|
37
|
+
}
|
|
38
|
+
export function ledgerPath(paths) {
|
|
39
|
+
return join(paths.cwdRoot(), LEDGER_FILE);
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Add one record. Append-only by construction: there is no update and no delete.
|
|
43
|
+
*
|
|
44
|
+
* Two callers, two different guarantees, and the difference is worth stating
|
|
45
|
+
* rather than glossing:
|
|
46
|
+
*
|
|
47
|
+
* - the **claim** appends inside the workspace lock that mints the slot, so the
|
|
48
|
+
* reservation and its record cannot separate;
|
|
49
|
+
* - the **release** at session close does NOT hold that lock — the close's
|
|
50
|
+
* reservation sweep is deliberately outside it and non-fatal — so its record
|
|
51
|
+
* is ordered by `O_APPEND` alone.
|
|
52
|
+
*
|
|
53
|
+
* That is sufficient here only because a record is one short line: `O_APPEND`
|
|
54
|
+
* makes a single small write atomic, so two processes appending cannot interleave
|
|
55
|
+
* halves of a record. It would stop being sufficient the day a record grew past a
|
|
56
|
+
* pipe buffer, which is the reason a record is one line and not a pretty-printed
|
|
57
|
+
* object.
|
|
58
|
+
*/
|
|
59
|
+
export async function appendClaimEvent(fs, paths, event) {
|
|
60
|
+
const record = { version: LEDGER_VERSION, ...event };
|
|
61
|
+
await fs.appendText(ledgerPath(paths), `${JSON.stringify(record)}\n`);
|
|
62
|
+
}
|
|
63
|
+
/** Every record, oldest first. A missing ledger reads as empty, never as an error. */
|
|
64
|
+
export async function readClaimEvents(fs, paths) {
|
|
65
|
+
const path = ledgerPath(paths);
|
|
66
|
+
if (!(await fs.exists(path)))
|
|
67
|
+
return { events: [], unreadable: 0 };
|
|
68
|
+
const raw = await fs.readText(path);
|
|
69
|
+
const events = [];
|
|
70
|
+
let unreadable = 0;
|
|
71
|
+
for (const line of raw.split("\n")) {
|
|
72
|
+
const trimmed = line.trim();
|
|
73
|
+
if (trimmed.length === 0)
|
|
74
|
+
continue;
|
|
75
|
+
const parsed = parseEvent(trimmed);
|
|
76
|
+
if (parsed === null)
|
|
77
|
+
unreadable += 1;
|
|
78
|
+
else
|
|
79
|
+
events.push(parsed);
|
|
80
|
+
}
|
|
81
|
+
return { events, unreadable };
|
|
82
|
+
}
|
|
83
|
+
function parseEvent(line) {
|
|
84
|
+
let value;
|
|
85
|
+
try {
|
|
86
|
+
value = JSON.parse(line);
|
|
87
|
+
}
|
|
88
|
+
catch {
|
|
89
|
+
return null;
|
|
90
|
+
}
|
|
91
|
+
if (typeof value !== "object" || value === null)
|
|
92
|
+
return null;
|
|
93
|
+
const candidate = value;
|
|
94
|
+
const claim = candidate.claim;
|
|
95
|
+
if (typeof candidate.at !== "string" ||
|
|
96
|
+
typeof candidate.event !== "string" ||
|
|
97
|
+
typeof claim !== "object" ||
|
|
98
|
+
claim === null ||
|
|
99
|
+
typeof claim.category !== "string" ||
|
|
100
|
+
typeof claim.correlative !== "string" ||
|
|
101
|
+
typeof claim.name !== "string" ||
|
|
102
|
+
typeof claim.owner !== "string") {
|
|
103
|
+
return null;
|
|
104
|
+
}
|
|
105
|
+
return value;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* The claims this owner still holds: a `claimed` with no terminal record after it.
|
|
109
|
+
*
|
|
110
|
+
* Derived rather than stored, because the ledger is append-only and a "still
|
|
111
|
+
* open" flag would be exactly the kind of mutable state that makes an
|
|
112
|
+
* append-only log pointless. `published`, `released` and `revoked` are all
|
|
113
|
+
* terminal — the first spends the number, the other two end the owner's hold on
|
|
114
|
+
* it — so any of them closes the claim for this reading.
|
|
115
|
+
*/
|
|
116
|
+
export function openClaimsOf(events, owner) {
|
|
117
|
+
const open = new Map();
|
|
118
|
+
for (const event of events) {
|
|
119
|
+
if (event.claim.owner !== owner)
|
|
120
|
+
continue;
|
|
121
|
+
const key = claimKey(event.claim);
|
|
122
|
+
if (event.event === "claimed")
|
|
123
|
+
open.set(key, event.claim);
|
|
124
|
+
else
|
|
125
|
+
open.delete(key);
|
|
126
|
+
}
|
|
127
|
+
return [...open.values()];
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* The claim a workspace-relative `docs/<category>/<NNN>-<name>` path would be.
|
|
131
|
+
*
|
|
132
|
+
* `null` for anything that is not a numbered document inside a category, which
|
|
133
|
+
* is what keeps this from reading a claim out of an unrelated destination.
|
|
134
|
+
*
|
|
135
|
+
* Exported because it is the ONE place that decides how a path splits into a
|
|
136
|
+
* claim identity: the publication reads it to credit a completion and the
|
|
137
|
+
* retirement reads it to name what it is giving back, and two spellings of that
|
|
138
|
+
* split would join to two different histories for the same slot.
|
|
139
|
+
*/
|
|
140
|
+
export function claimOfDocsPath(path, owner) {
|
|
141
|
+
const parts = path.split("/").filter((segment) => segment.length > 0);
|
|
142
|
+
const docsAt = parts.indexOf("docs");
|
|
143
|
+
if (docsAt === -1 || parts.length - docsAt !== 3)
|
|
144
|
+
return null;
|
|
145
|
+
const category = parts[docsAt + 1];
|
|
146
|
+
const file = parts[docsAt + 2];
|
|
147
|
+
if (category === undefined || file === undefined)
|
|
148
|
+
return null;
|
|
149
|
+
const match = /^(\d{3,})-(.+)$/.exec(file);
|
|
150
|
+
if (match?.[1] === undefined || match[2] === undefined)
|
|
151
|
+
return null;
|
|
152
|
+
return { category, correlative: match[1], name: match[2], owner };
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Which claims of this owner a publication just completed.
|
|
156
|
+
*
|
|
157
|
+
* The whole decision of "did this write finish a reservation of mine?" lives
|
|
158
|
+
* here rather than at the publication site, and getting it wrong is durable in
|
|
159
|
+
* both directions:
|
|
160
|
+
*
|
|
161
|
+
* - **Under-crediting** leaves a claim open about a correlative that is holding a
|
|
162
|
+
* published document, which invites a later recovery to release live bytes.
|
|
163
|
+
* That is why `already_applied` is handled here: the re-entry that finds the
|
|
164
|
+
* document already on disk reports `written: []`, and crediting only `written`
|
|
165
|
+
* left the claim open FOREVER — every retry answers the same way, so nothing
|
|
166
|
+
* could ever correct it. When the apply says already-applied, every destination
|
|
167
|
+
* holds exactly the proposed bytes, so the destinations are the candidates.
|
|
168
|
+
* - **Over-crediting** writes a permanent "spent forever" fence on a correlative
|
|
169
|
+
* the session never reserved. So a candidate only counts when it closes one of
|
|
170
|
+
* THIS owner's open claims, read from the ledger — not from the shape of
|
|
171
|
+
* whatever proposal happened to carry the write. Every flow's publication goes
|
|
172
|
+
* through this same path, not only the one whose single artifact is its own slot.
|
|
173
|
+
*
|
|
174
|
+
* Both directions had a surviving mutant when this logic sat inlined at the call
|
|
175
|
+
* site, which is the other reason it is here: it is testable in isolation.
|
|
176
|
+
*/
|
|
177
|
+
export function completedClaimsIn(events, owner, publication) {
|
|
178
|
+
const candidates = publication.already_applied ? publication.destinations : publication.written;
|
|
179
|
+
if (candidates.length === 0)
|
|
180
|
+
return [];
|
|
181
|
+
const open = new Set(openClaimsOf(events, owner).map((claim) => claimKey(claim)));
|
|
182
|
+
if (open.size === 0)
|
|
183
|
+
return [];
|
|
184
|
+
const completed = [];
|
|
185
|
+
for (const path of candidates) {
|
|
186
|
+
const claim = claimOfDocsPath(path, owner);
|
|
187
|
+
if (claim === null || !open.has(claimKey(claim)))
|
|
188
|
+
continue;
|
|
189
|
+
completed.push(claim);
|
|
190
|
+
}
|
|
191
|
+
return completed;
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Every claim this ledger has ever revoked.
|
|
195
|
+
*
|
|
196
|
+
* Membership is permanent by construction: one `revoked` record fences the claim
|
|
197
|
+
* forever, and no later record lifts it. That is what "irrevocable" has to mean
|
|
198
|
+
* to be worth anything — a fence somebody can reopen is not a fence, and the
|
|
199
|
+
* whole reason a recovery may free a correlative is that no late publication can
|
|
200
|
+
* still land on it.
|
|
201
|
+
*/
|
|
202
|
+
function revokedKeys(events) {
|
|
203
|
+
const revoked = new Set();
|
|
204
|
+
for (const event of events) {
|
|
205
|
+
if (event.event === "revoked")
|
|
206
|
+
revoked.add(claimKey(event.claim));
|
|
207
|
+
}
|
|
208
|
+
return revoked;
|
|
209
|
+
}
|
|
210
|
+
/** Whether this exact claim is fenced. */
|
|
211
|
+
export function isRevoked(events, claim) {
|
|
212
|
+
return revokedKeys(events).has(claimKey(claim));
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* The destinations of a publication that a revocation forbids.
|
|
216
|
+
*
|
|
217
|
+
* Checked at the publication point rather than at the release: once a recovery
|
|
218
|
+
* has freed a correlative, the slot no longer exists on disk, so a late sealed
|
|
219
|
+
* proposal would read its destination as a plain creation and land a document on
|
|
220
|
+
* a number that may already belong to somebody else. The fence is the only thing
|
|
221
|
+
* standing between "the reservation was recovered" and "two documents share a
|
|
222
|
+
* correlative".
|
|
223
|
+
*/
|
|
224
|
+
export function revokedAmong(events, owner, destinations) {
|
|
225
|
+
const revoked = revokedKeys(events);
|
|
226
|
+
if (revoked.size === 0)
|
|
227
|
+
return [];
|
|
228
|
+
const blocked = [];
|
|
229
|
+
for (const path of destinations) {
|
|
230
|
+
const claim = claimOfDocsPath(path, owner);
|
|
231
|
+
if (claim === null || !revoked.has(claimKey(claim)))
|
|
232
|
+
continue;
|
|
233
|
+
blocked.push(claim);
|
|
234
|
+
}
|
|
235
|
+
return blocked;
|
|
236
|
+
}
|
|
237
|
+
/**
|
|
238
|
+
* Destinations that look like a numbered document of this owner's category space.
|
|
239
|
+
*
|
|
240
|
+
* Used only to scope the fail-closed: a ledger with unreadable lines cannot prove
|
|
241
|
+
* the ABSENCE of a revocation, so a publication that could be completing a
|
|
242
|
+
* reservation must refuse rather than guess. A write that is not a numbered
|
|
243
|
+
* document in a category cannot be a reservation, so it is never held up by a
|
|
244
|
+
* ledger it does not depend on.
|
|
245
|
+
*/
|
|
246
|
+
export function claimShapedAmong(owner, destinations) {
|
|
247
|
+
const shaped = [];
|
|
248
|
+
for (const path of destinations) {
|
|
249
|
+
const claim = claimOfDocsPath(path, owner);
|
|
250
|
+
if (claim !== null)
|
|
251
|
+
shaped.push(claim);
|
|
252
|
+
}
|
|
253
|
+
return shaped;
|
|
254
|
+
}
|
|
255
|
+
function sameSlot(claim, slot) {
|
|
256
|
+
return (claim.category === slot.category &&
|
|
257
|
+
claim.correlative === slot.correlative &&
|
|
258
|
+
claim.name === slot.name);
|
|
259
|
+
}
|
|
260
|
+
/**
|
|
261
|
+
* Whether this slot was ever published, by anyone.
|
|
262
|
+
*
|
|
263
|
+
* Asked BEFORE the bytes are interpreted, because bytes lie in one direction that
|
|
264
|
+
* matters: a published document whose content happens to be empty looks exactly
|
|
265
|
+
* like the legacy placeholder a recovery is allowed to delete. The record knows
|
|
266
|
+
* the difference and the file does not, so the record decides.
|
|
267
|
+
*/
|
|
268
|
+
export function wasPublished(events, slot) {
|
|
269
|
+
return events.some((event) => event.event === "published" && sameSlot(event.claim, slot));
|
|
270
|
+
}
|
|
271
|
+
/**
|
|
272
|
+
* The owner whose claim on this slot is still open, or `null`.
|
|
273
|
+
*
|
|
274
|
+
* Lets a file that is no longer its own intact marker — emptied by an editor, a
|
|
275
|
+
* `> file`, a checkout — still be attributed to the session that reserved it.
|
|
276
|
+
* Without this the same file reads as ownerless, and freeing it would give the
|
|
277
|
+
* correlative back with no fence for the owner that is still holding it.
|
|
278
|
+
*/
|
|
279
|
+
export function openOwnerOfSlot(events, slot) {
|
|
280
|
+
let open = null;
|
|
281
|
+
for (const event of events) {
|
|
282
|
+
if (!sameSlot(event.claim, slot))
|
|
283
|
+
continue;
|
|
284
|
+
open = event.event === "claimed" ? event.claim : null;
|
|
285
|
+
}
|
|
286
|
+
return open;
|
|
287
|
+
}
|
|
288
|
+
/**
|
|
289
|
+
* Correlatives of this category that were released and never published, ascending.
|
|
290
|
+
*
|
|
291
|
+
* The second reason this ledger exists. Minting used to compute `max + 1` and
|
|
292
|
+
* probe forward only, so a correlative given back in the middle of the range was
|
|
293
|
+
* lost forever — this workspace's own `docs/plans` has a permanent hole at `033`
|
|
294
|
+
* from exactly that. Only the record can tell a number that came back from one
|
|
295
|
+
* that never existed, because the disk looks identical either way.
|
|
296
|
+
*
|
|
297
|
+
* Judged per (category, correlative) and by the LAST terminal record, not by the
|
|
298
|
+
* presence of any: a number can be released, re-claimed and then published, and
|
|
299
|
+
* after that it is spent. `published` is the one state that never becomes eligible
|
|
300
|
+
* again — a correlative holding a document is not a free number, whatever else
|
|
301
|
+
* the history says about it.
|
|
302
|
+
*
|
|
303
|
+
* Ascending because the rule has to be deterministic and reproducible, and
|
|
304
|
+
* lowest-first also fills the holes rather than growing the range. The caller is
|
|
305
|
+
* still responsible for skipping anything taken on disk: this answers "did the
|
|
306
|
+
* record give it back", never "is the name free right now".
|
|
307
|
+
*/
|
|
308
|
+
export function eligibleCorrelatives(events, category) {
|
|
309
|
+
const state = new Map();
|
|
310
|
+
for (const event of events) {
|
|
311
|
+
if (event.claim.category !== category)
|
|
312
|
+
continue;
|
|
313
|
+
if (event.event === "claimed")
|
|
314
|
+
continue;
|
|
315
|
+
state.set(event.claim.correlative, event.event);
|
|
316
|
+
}
|
|
317
|
+
const eligible = [];
|
|
318
|
+
for (const [correlative, last] of state) {
|
|
319
|
+
// Validated before it can be handed out. A single semi-valid ledger line
|
|
320
|
+
// would otherwise put a non-correlative into the mint, where it becomes an
|
|
321
|
+
// unrecognizable filename or a throw on the comparator.
|
|
322
|
+
if (last === "released" && isCorrelative(correlative))
|
|
323
|
+
eligible.push(correlative);
|
|
324
|
+
}
|
|
325
|
+
// `compareCorrelatives` and not a hand-rolled numeric sort: it is bigint-based,
|
|
326
|
+
// so it stays correct past the width where `parseInt` loses precision — and a
|
|
327
|
+
// second ordering rule for the same domain type is a second thing to keep true.
|
|
328
|
+
return eligible.sort(compareCorrelatives);
|
|
329
|
+
}
|
|
330
|
+
//# sourceMappingURL=claims-ledger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claims-ledger.js","sourceRoot":"","sources":["../../src/application/claims-ledger.ts"],"names":[],"mappings":"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"}
|