@cluesmith/codev 3.3.4 → 3.3.6
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/dashboard-dist/assets/index-BjcqV9Vv.css +32 -0
- package/dashboard-dist/assets/index-b7GnZV2i.js +220 -0
- package/dashboard-dist/assets/index-b7GnZV2i.js.map +1 -0
- package/dashboard-dist/index.html +2 -2
- package/dist/agent-farm/cli.d.ts.map +1 -1
- package/dist/agent-farm/cli.js +50 -17
- package/dist/agent-farm/cli.js.map +1 -1
- package/dist/agent-farm/commands/architect.d.ts.map +1 -1
- package/dist/agent-farm/commands/architect.js +5 -1
- package/dist/agent-farm/commands/architect.js.map +1 -1
- package/dist/agent-farm/commands/attach.d.ts +1 -1
- package/dist/agent-farm/commands/attach.d.ts.map +1 -1
- package/dist/agent-farm/commands/cleanup.d.ts +1 -1
- package/dist/agent-farm/commands/cleanup.d.ts.map +1 -1
- package/dist/agent-farm/commands/cleanup.js +2 -1
- package/dist/agent-farm/commands/cleanup.js.map +1 -1
- package/dist/agent-farm/commands/decisions.d.ts +25 -0
- package/dist/agent-farm/commands/decisions.d.ts.map +1 -0
- package/dist/agent-farm/commands/decisions.js +54 -0
- package/dist/agent-farm/commands/decisions.js.map +1 -0
- package/dist/agent-farm/commands/ide.d.ts +32 -3
- package/dist/agent-farm/commands/ide.d.ts.map +1 -1
- package/dist/agent-farm/commands/ide.js +180 -19
- package/dist/agent-farm/commands/ide.js.map +1 -1
- package/dist/agent-farm/commands/reset/context.d.ts +4 -2
- package/dist/agent-farm/commands/reset/context.d.ts.map +1 -1
- package/dist/agent-farm/commands/reset/context.js +12 -4
- package/dist/agent-farm/commands/reset/context.js.map +1 -1
- package/dist/agent-farm/commands/send.d.ts +3 -2
- package/dist/agent-farm/commands/send.d.ts.map +1 -1
- package/dist/agent-farm/commands/send.js +35 -21
- package/dist/agent-farm/commands/send.js.map +1 -1
- package/dist/agent-farm/commands/spawn-worktree.d.ts +7 -0
- package/dist/agent-farm/commands/spawn-worktree.d.ts.map +1 -1
- package/dist/agent-farm/commands/spawn-worktree.js +63 -20
- package/dist/agent-farm/commands/spawn-worktree.js.map +1 -1
- package/dist/agent-farm/commands/spawn.d.ts +17 -0
- package/dist/agent-farm/commands/spawn.d.ts.map +1 -1
- package/dist/agent-farm/commands/spawn.js +41 -19
- package/dist/agent-farm/commands/spawn.js.map +1 -1
- package/dist/agent-farm/lib/builder-lookup.d.ts +3 -2
- package/dist/agent-farm/lib/builder-lookup.d.ts.map +1 -1
- package/dist/agent-farm/lib/builder-lookup.js +24 -9
- package/dist/agent-farm/lib/builder-lookup.js.map +1 -1
- package/dist/agent-farm/lib/ide-extensions.d.ts +82 -0
- package/dist/agent-farm/lib/ide-extensions.d.ts.map +1 -0
- package/dist/agent-farm/lib/ide-extensions.js +179 -0
- package/dist/agent-farm/lib/ide-extensions.js.map +1 -0
- package/dist/agent-farm/lib/ide-record.d.ts +6 -1
- package/dist/agent-farm/lib/ide-record.d.ts.map +1 -1
- package/dist/agent-farm/lib/ide-record.js +8 -1
- package/dist/agent-farm/lib/ide-record.js.map +1 -1
- package/dist/agent-farm/lib/ide-version.d.ts +97 -0
- package/dist/agent-farm/lib/ide-version.d.ts.map +1 -0
- package/dist/agent-farm/lib/ide-version.js +224 -0
- package/dist/agent-farm/lib/ide-version.js.map +1 -0
- package/dist/agent-farm/lib/tunnel-client.d.ts.map +1 -1
- package/dist/agent-farm/lib/tunnel-client.js +7 -3
- package/dist/agent-farm/lib/tunnel-client.js.map +1 -1
- package/dist/agent-farm/servers/agent-state/broadcast.d.ts +19 -0
- package/dist/agent-farm/servers/agent-state/broadcast.d.ts.map +1 -0
- package/dist/agent-farm/servers/agent-state/broadcast.js +30 -0
- package/dist/agent-farm/servers/agent-state/broadcast.js.map +1 -0
- package/dist/agent-farm/servers/agent-state/identity.d.ts +50 -0
- package/dist/agent-farm/servers/agent-state/identity.d.ts.map +1 -0
- package/dist/agent-farm/servers/agent-state/identity.js +120 -0
- package/dist/agent-farm/servers/agent-state/identity.js.map +1 -0
- package/dist/agent-farm/servers/agent-state/liveness.d.ts +107 -0
- package/dist/agent-farm/servers/agent-state/liveness.d.ts.map +1 -0
- package/dist/agent-farm/servers/agent-state/liveness.js +224 -0
- package/dist/agent-farm/servers/agent-state/liveness.js.map +1 -0
- package/dist/agent-farm/servers/agent-state/route.d.ts +38 -0
- package/dist/agent-farm/servers/agent-state/route.d.ts.map +1 -0
- package/dist/agent-farm/servers/agent-state/route.js +170 -0
- package/dist/agent-farm/servers/agent-state/route.js.map +1 -0
- package/dist/agent-farm/servers/agent-state/serve.d.ts +31 -0
- package/dist/agent-farm/servers/agent-state/serve.d.ts.map +1 -0
- package/dist/agent-farm/servers/agent-state/serve.js +49 -0
- package/dist/agent-farm/servers/agent-state/serve.js.map +1 -0
- package/dist/agent-farm/servers/agent-state/store.d.ts +76 -0
- package/dist/agent-farm/servers/agent-state/store.d.ts.map +1 -0
- package/dist/agent-farm/servers/agent-state/store.js +157 -0
- package/dist/agent-farm/servers/agent-state/store.js.map +1 -0
- package/dist/agent-farm/servers/decisions/file.d.ts +50 -0
- package/dist/agent-farm/servers/decisions/file.d.ts.map +1 -0
- package/dist/agent-farm/servers/decisions/file.js +146 -0
- package/dist/agent-farm/servers/decisions/file.js.map +1 -0
- package/dist/agent-farm/servers/decisions/grammar.d.ts +36 -0
- package/dist/agent-farm/servers/decisions/grammar.d.ts.map +1 -0
- package/dist/agent-farm/servers/decisions/grammar.js +109 -0
- package/dist/agent-farm/servers/decisions/grammar.js.map +1 -0
- package/dist/agent-farm/servers/decisions/notice.d.ts +11 -0
- package/dist/agent-farm/servers/decisions/notice.d.ts.map +1 -0
- package/dist/agent-farm/servers/decisions/notice.js +18 -0
- package/dist/agent-farm/servers/decisions/notice.js.map +1 -0
- package/dist/agent-farm/servers/decisions/parse.d.ts +36 -0
- package/dist/agent-farm/servers/decisions/parse.d.ts.map +1 -0
- package/dist/agent-farm/servers/decisions/parse.js +338 -0
- package/dist/agent-farm/servers/decisions/parse.js.map +1 -0
- package/dist/agent-farm/servers/decisions/routes.d.ts +17 -0
- package/dist/agent-farm/servers/decisions/routes.d.ts.map +1 -0
- package/dist/agent-farm/servers/decisions/routes.js +160 -0
- package/dist/agent-farm/servers/decisions/routes.js.map +1 -0
- package/dist/agent-farm/servers/decisions/splice.d.ts +26 -0
- package/dist/agent-farm/servers/decisions/splice.d.ts.map +1 -0
- package/dist/agent-farm/servers/decisions/splice.js +120 -0
- package/dist/agent-farm/servers/decisions/splice.js.map +1 -0
- package/dist/agent-farm/servers/decisions/stamp.d.ts +8 -0
- package/dist/agent-farm/servers/decisions/stamp.d.ts.map +1 -0
- package/dist/agent-farm/servers/decisions/stamp.js +195 -0
- package/dist/agent-farm/servers/decisions/stamp.js.map +1 -0
- package/dist/agent-farm/servers/decisions/template.d.ts +2 -0
- package/dist/agent-farm/servers/decisions/template.d.ts.map +1 -0
- package/dist/agent-farm/servers/decisions/template.js +15 -0
- package/dist/agent-farm/servers/decisions/template.js.map +1 -0
- package/dist/agent-farm/servers/ide-server.d.ts +28 -8
- package/dist/agent-farm/servers/ide-server.d.ts.map +1 -1
- package/dist/agent-farm/servers/ide-server.js +147 -50
- package/dist/agent-farm/servers/ide-server.js.map +1 -1
- package/dist/agent-farm/servers/overview.d.ts +31 -4
- package/dist/agent-farm/servers/overview.d.ts.map +1 -1
- package/dist/agent-farm/servers/overview.js +235 -55
- package/dist/agent-farm/servers/overview.js.map +1 -1
- package/dist/agent-farm/servers/tower-instances.d.ts +14 -1
- package/dist/agent-farm/servers/tower-instances.d.ts.map +1 -1
- package/dist/agent-farm/servers/tower-instances.js +51 -9
- package/dist/agent-farm/servers/tower-instances.js.map +1 -1
- package/dist/agent-farm/servers/tower-routes.d.ts.map +1 -1
- package/dist/agent-farm/servers/tower-routes.js +113 -14
- package/dist/agent-farm/servers/tower-routes.js.map +1 -1
- package/dist/agent-farm/servers/tower-server.js +35 -1
- package/dist/agent-farm/servers/tower-server.js.map +1 -1
- package/dist/agent-farm/servers/tower-terminals.d.ts +25 -0
- package/dist/agent-farm/servers/tower-terminals.d.ts.map +1 -1
- package/dist/agent-farm/servers/tower-terminals.js +128 -4
- package/dist/agent-farm/servers/tower-terminals.js.map +1 -1
- package/dist/agent-farm/servers/tower-utils.d.ts.map +1 -1
- package/dist/agent-farm/servers/tower-utils.js +18 -5
- package/dist/agent-farm/servers/tower-utils.js.map +1 -1
- package/dist/agent-farm/utils/builder-worktree-identity.d.ts +39 -0
- package/dist/agent-farm/utils/builder-worktree-identity.d.ts.map +1 -0
- package/dist/agent-farm/utils/builder-worktree-identity.js +42 -0
- package/dist/agent-farm/utils/builder-worktree-identity.js.map +1 -0
- package/dist/agent-farm/utils/harness.d.ts +71 -0
- package/dist/agent-farm/utils/harness.d.ts.map +1 -1
- package/dist/agent-farm/utils/harness.js +153 -0
- package/dist/agent-farm/utils/harness.js.map +1 -1
- package/dist/agent-farm/utils/lifecycle-reporter.d.ts +79 -0
- package/dist/agent-farm/utils/lifecycle-reporter.d.ts.map +1 -0
- package/dist/agent-farm/utils/lifecycle-reporter.js +347 -0
- package/dist/agent-farm/utils/lifecycle-reporter.js.map +1 -0
- package/dist/agent-farm/utils/message-format.d.ts +8 -0
- package/dist/agent-farm/utils/message-format.d.ts.map +1 -1
- package/dist/agent-farm/utils/message-format.js +16 -0
- package/dist/agent-farm/utils/message-format.js.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +17 -0
- package/dist/cli.js.map +1 -1
- package/dist/commands/adopt.d.ts +16 -2
- package/dist/commands/adopt.d.ts.map +1 -1
- package/dist/commands/adopt.js +67 -23
- package/dist/commands/adopt.js.map +1 -1
- package/dist/commands/bootstrap-docs.d.ts +132 -0
- package/dist/commands/bootstrap-docs.d.ts.map +1 -0
- package/dist/commands/bootstrap-docs.js +725 -0
- package/dist/commands/bootstrap-docs.js.map +1 -0
- package/dist/commands/consult/index.d.ts +20 -1
- package/dist/commands/consult/index.d.ts.map +1 -1
- package/dist/commands/consult/index.js +70 -3
- package/dist/commands/consult/index.js.map +1 -1
- package/dist/commands/consult/tree-tripwire.d.ts +2 -75
- package/dist/commands/consult/tree-tripwire.d.ts.map +1 -1
- package/dist/commands/consult/tree-tripwire.js +7 -184
- package/dist/commands/consult/tree-tripwire.js.map +1 -1
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +36 -4
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/porch/checks.d.ts +7 -1
- package/dist/commands/porch/checks.d.ts.map +1 -1
- package/dist/commands/porch/checks.js +77 -14
- package/dist/commands/porch/checks.js.map +1 -1
- package/dist/commands/porch/index.d.ts +38 -1
- package/dist/commands/porch/index.d.ts.map +1 -1
- package/dist/commands/porch/index.js +79 -43
- package/dist/commands/porch/index.js.map +1 -1
- package/dist/commands/porch/protocol.d.ts +4 -3
- package/dist/commands/porch/protocol.d.ts.map +1 -1
- package/dist/commands/porch/protocol.js +32 -5
- package/dist/commands/porch/protocol.js.map +1 -1
- package/dist/commands/porch/state.d.ts +0 -4
- package/dist/commands/porch/state.d.ts.map +1 -1
- package/dist/commands/porch/state.js +23 -10
- package/dist/commands/porch/state.js.map +1 -1
- package/dist/commands/porch/types.d.ts +2 -0
- package/dist/commands/porch/types.d.ts.map +1 -1
- package/dist/commands/update.d.ts +5 -1
- package/dist/commands/update.d.ts.map +1 -1
- package/dist/commands/update.js +73 -18
- package/dist/commands/update.js.map +1 -1
- package/dist/lib/agent-env.d.ts +31 -1
- package/dist/lib/agent-env.d.ts.map +1 -1
- package/dist/lib/agent-env.js +38 -1
- package/dist/lib/agent-env.js.map +1 -1
- package/dist/lib/agent-process.d.ts +23 -0
- package/dist/lib/agent-process.d.ts.map +1 -0
- package/dist/lib/agent-process.js +24 -0
- package/dist/lib/agent-process.js.map +1 -0
- package/dist/lib/config.d.ts +8 -0
- package/dist/lib/config.d.ts.map +1 -1
- package/dist/lib/config.js.map +1 -1
- package/dist/lib/forge-contracts.d.ts +9 -3
- package/dist/lib/forge-contracts.d.ts.map +1 -1
- package/dist/lib/forge-contracts.js.map +1 -1
- package/dist/lib/forge.d.ts +8 -5
- package/dist/lib/forge.d.ts.map +1 -1
- package/dist/lib/forge.js +57 -1
- package/dist/lib/forge.js.map +1 -1
- package/dist/lib/github.d.ts.map +1 -1
- package/dist/lib/github.js +38 -0
- package/dist/lib/github.js.map +1 -1
- package/dist/lib/governance-bootstrap.d.ts +155 -0
- package/dist/lib/governance-bootstrap.d.ts.map +1 -0
- package/dist/lib/governance-bootstrap.js +469 -0
- package/dist/lib/governance-bootstrap.js.map +1 -0
- package/dist/lib/issue-id.d.ts +34 -0
- package/dist/lib/issue-id.d.ts.map +1 -0
- package/dist/lib/issue-id.js +61 -0
- package/dist/lib/issue-id.js.map +1 -0
- package/dist/lib/scaffold.d.ts +4 -0
- package/dist/lib/scaffold.d.ts.map +1 -1
- package/dist/lib/scaffold.js +29 -5
- package/dist/lib/scaffold.js.map +1 -1
- package/dist/lib/shipped-skill-hashes.d.ts +10 -0
- package/dist/lib/shipped-skill-hashes.d.ts.map +1 -0
- package/dist/lib/shipped-skill-hashes.js +197 -0
- package/dist/lib/shipped-skill-hashes.js.map +1 -0
- package/dist/lib/skill-refresh.d.ts +90 -0
- package/dist/lib/skill-refresh.d.ts.map +1 -0
- package/dist/lib/skill-refresh.js +267 -0
- package/dist/lib/skill-refresh.js.map +1 -0
- package/dist/lib/tree-snapshot.d.ts +172 -0
- package/dist/lib/tree-snapshot.d.ts.map +1 -0
- package/dist/lib/tree-snapshot.js +393 -0
- package/dist/lib/tree-snapshot.js.map +1 -0
- package/dist/terminal/pty-session.d.ts +5 -0
- package/dist/terminal/pty-session.d.ts.map +1 -1
- package/dist/terminal/pty-session.js +7 -0
- package/dist/terminal/pty-session.js.map +1 -1
- package/ide-extension/codev-vscode.vsix +0 -0
- package/ide-extension/manifest.json +7 -0
- package/package.json +8 -6
- package/scripts/forge/jira/_lib.sh +113 -0
- package/scripts/forge/jira/auth-status.sh +29 -0
- package/scripts/forge/jira/issue-comment.sh +23 -0
- package/scripts/forge/jira/issue-list.sh +32 -0
- package/scripts/forge/jira/issue-search.sh +40 -0
- package/scripts/forge/jira/issue-view.sh +41 -0
- package/scripts/forge/jira/recently-closed.sh +81 -0
- package/scripts/forge/jira/user-identity.sh +18 -0
- package/skeleton/.claude/skills/afx/SKILL.md +51 -0
- package/skeleton/.claude/skills/arch-init/SKILL.md +56 -9
- package/skeleton/.claude/skills/arch-save/SKILL.md +100 -9
- package/skeleton/.claude/skills/codev/SKILL.md +18 -2
- package/skeleton/.claude/skills/consult/SKILL.md +9 -0
- package/skeleton/.claude/skills/porch/SKILL.md +18 -0
- package/skeleton/.claude/skills/update-arch-docs/SKILL.md +28 -2
- package/skeleton/.codex/skills/afx/SKILL.md +51 -0
- package/skeleton/.codex/skills/arch-init/SKILL.md +56 -9
- package/skeleton/.codex/skills/arch-save/SKILL.md +100 -9
- package/skeleton/.codex/skills/codev/SKILL.md +18 -2
- package/skeleton/.codex/skills/consult/SKILL.md +9 -0
- package/skeleton/.codex/skills/porch/SKILL.md +18 -0
- package/skeleton/.codex/skills/update-arch-docs/SKILL.md +28 -2
- package/skeleton/protocol-schema.json +6 -0
- package/skeleton/protocols/maintain/protocol.md +5 -0
- package/skeleton/protocols/pir/prompts/review.md +0 -1
- package/skeleton/protocols/protocol-schema.json +6 -0
- package/skeleton/resources/commands/agent-farm.md +156 -0
- package/skeleton/resources/commands/codev.md +47 -0
- package/skeleton/resources/commands/consult.md +9 -2
- package/skeleton/resources/commands/overview.md +1 -0
- package/skeleton/resources/decision-protocol.md +215 -0
- package/skeleton/resources/workflow-reference.md +12 -0
- package/skeleton/roles/architect.md +6 -0
- package/skeleton/templates/bootstrap-docs-prompt.md +16 -0
- package/skeleton/templates/bootstrap-docs-review-prompt.md +19 -0
- package/skeleton/templates/cheatsheet.md +2 -1
- package/dashboard-dist/assets/index-DZf6pNPE.js +0 -199
- package/dashboard-dist/assets/index-DZf6pNPE.js.map +0 -1
- package/dashboard-dist/assets/index-DnYLy5C_.css +0 -32
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
// The decisions file on disk (Spec 1819): where it is, whether it may be touched,
|
|
2
|
+
// and how a ruling replaces it.
|
|
3
|
+
//
|
|
4
|
+
// The path comes from `dashboard.decisionsFile` (workspace-relative), never from a
|
|
5
|
+
// request. Every read and write canonicalizes it — symlinks followed — and refuses a
|
|
6
|
+
// target outside the canonical workspace root. Writes go through one serializer per
|
|
7
|
+
// canonical path and replace the file by renaming a fully written, fsynced temporary
|
|
8
|
+
// file over it, so a crash leaves the old file or the new one, never a truncated one.
|
|
9
|
+
import crypto from 'node:crypto';
|
|
10
|
+
import { promises as fsp } from 'node:fs';
|
|
11
|
+
import path from 'node:path';
|
|
12
|
+
import { loadConfig } from '../../../lib/config.js';
|
|
13
|
+
import { KeyedSerializer } from '../write-queue.js';
|
|
14
|
+
export const DEFAULT_DECISIONS_FILE = 'codev/state/pending-decisions.md';
|
|
15
|
+
/** How long the state flag may reuse a workspace's configured path. */
|
|
16
|
+
export const CONFIGURED_PATH_MEMO_MS = 5_000;
|
|
17
|
+
const configuredPathMemo = new Map();
|
|
18
|
+
/** At most one write per canonical decisions file runs at a time. */
|
|
19
|
+
export const decisionsWriteQueue = new KeyedSerializer();
|
|
20
|
+
function readConfiguredPath(workspacePath) {
|
|
21
|
+
try {
|
|
22
|
+
const value = loadConfig(workspacePath).dashboard?.decisionsFile;
|
|
23
|
+
if (value === undefined)
|
|
24
|
+
return { ok: true, path: DEFAULT_DECISIONS_FILE };
|
|
25
|
+
if (typeof value !== 'string' || value.trim() === '') {
|
|
26
|
+
throw new Error(`dashboard.decisionsFile must be a non-empty string, got ${JSON.stringify(value)}`);
|
|
27
|
+
}
|
|
28
|
+
if (path.isAbsolute(value)) {
|
|
29
|
+
throw new Error(`dashboard.decisionsFile must be relative to the workspace root, got ${JSON.stringify(value)}`);
|
|
30
|
+
}
|
|
31
|
+
return { ok: true, path: value };
|
|
32
|
+
}
|
|
33
|
+
catch (err) {
|
|
34
|
+
return { ok: false, error: err };
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* The workspace's configured decisions path (relative to its root). `fresh` reads the
|
|
39
|
+
* config now — the routes always do; otherwise a result up to
|
|
40
|
+
* {@link CONFIGURED_PATH_MEMO_MS} old is reused, because the state flag is polled every
|
|
41
|
+
* second by every open dashboard. The memo holds only the configured path (or the
|
|
42
|
+
* config error), never the decisions file's content. Throws the config error.
|
|
43
|
+
*/
|
|
44
|
+
export function configuredDecisionsPath(workspacePath, { fresh }) {
|
|
45
|
+
const memo = configuredPathMemo.get(workspacePath);
|
|
46
|
+
let outcome;
|
|
47
|
+
if (!fresh && memo && Date.now() - memo.at < CONFIGURED_PATH_MEMO_MS) {
|
|
48
|
+
outcome = memo.outcome;
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
outcome = readConfiguredPath(workspacePath);
|
|
52
|
+
configuredPathMemo.set(workspacePath, { at: Date.now(), outcome });
|
|
53
|
+
}
|
|
54
|
+
if (!outcome.ok)
|
|
55
|
+
throw outcome.error;
|
|
56
|
+
return outcome.path;
|
|
57
|
+
}
|
|
58
|
+
/** Canonicalize a path that may not exist: realpath its nearest existing ancestor. */
|
|
59
|
+
async function canonicalize(target) {
|
|
60
|
+
const missing = [];
|
|
61
|
+
let existing = target;
|
|
62
|
+
for (;;) {
|
|
63
|
+
try {
|
|
64
|
+
return path.join(await fsp.realpath(existing), ...missing);
|
|
65
|
+
}
|
|
66
|
+
catch (err) {
|
|
67
|
+
const parent = path.dirname(existing);
|
|
68
|
+
if (err.code !== 'ENOENT' || parent === existing)
|
|
69
|
+
throw err;
|
|
70
|
+
missing.unshift(path.basename(existing));
|
|
71
|
+
existing = parent;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
function isInside(root, candidate) {
|
|
76
|
+
const relative = path.relative(root, candidate);
|
|
77
|
+
return relative !== '' && relative !== '..' && !relative.startsWith(`..${path.sep}`) && !path.isAbsolute(relative);
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Resolve the configured path against the workspace root. Both are canonicalized
|
|
81
|
+
* (symlinks followed; a missing target through its nearest existing ancestor), and a
|
|
82
|
+
* canonical target outside the canonical root is reported as `inside: false`.
|
|
83
|
+
*/
|
|
84
|
+
export async function resolveDecisionsPath(workspacePath, configuredPath) {
|
|
85
|
+
const root = await fsp.realpath(workspacePath);
|
|
86
|
+
const target = path.resolve(root, configuredPath);
|
|
87
|
+
const displayPath = path.relative(root, target).split(path.sep).join('/');
|
|
88
|
+
const canonicalPath = await canonicalize(target);
|
|
89
|
+
if (!isInside(root, canonicalPath))
|
|
90
|
+
return { inside: false, displayPath, canonicalPath };
|
|
91
|
+
const stat = await fsp.stat(canonicalPath).catch((err) => {
|
|
92
|
+
if (err.code === 'ENOENT')
|
|
93
|
+
return null;
|
|
94
|
+
throw err;
|
|
95
|
+
});
|
|
96
|
+
return { inside: true, canonicalPath, displayPath, exists: stat?.isFile() ?? false };
|
|
97
|
+
}
|
|
98
|
+
/** The last presence-check error logged per workspace, so a poll logs it once, not every second. */
|
|
99
|
+
const loggedPresenceError = new Map();
|
|
100
|
+
/**
|
|
101
|
+
* Whether the Decisions tab should show: the configured file exists inside the
|
|
102
|
+
* workspace. Uses the memoized configured path. A config error is logged and reads as
|
|
103
|
+
* false — it must never fail the state response; the decisions routes report it in full.
|
|
104
|
+
*/
|
|
105
|
+
export async function decisionsFilePresent(workspacePath, log) {
|
|
106
|
+
try {
|
|
107
|
+
const resolved = await resolveDecisionsPath(workspacePath, configuredDecisionsPath(workspacePath, { fresh: false }));
|
|
108
|
+
loggedPresenceError.delete(workspacePath);
|
|
109
|
+
return resolved.inside && resolved.exists;
|
|
110
|
+
}
|
|
111
|
+
catch (err) {
|
|
112
|
+
const message = err.message;
|
|
113
|
+
if (loggedPresenceError.get(workspacePath) !== message) {
|
|
114
|
+
loggedPresenceError.set(workspacePath, message);
|
|
115
|
+
log('WARN', `Decisions tab hidden for ${workspacePath}: ${message}`);
|
|
116
|
+
}
|
|
117
|
+
return false;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Replace `target` with `text`: write a temporary file in the same directory with the
|
|
122
|
+
* target's permissions, fsync it, and rename it over the target. The temporary file is
|
|
123
|
+
* removed if any step fails, leaving the target untouched. `target` must be the
|
|
124
|
+
* canonical path, so a symlink pointing at it is left in place.
|
|
125
|
+
*/
|
|
126
|
+
export async function writeFileAtomic(target, text) {
|
|
127
|
+
const mode = (await fsp.stat(target)).mode & 0o7777;
|
|
128
|
+
const temp = path.join(path.dirname(target), `.${path.basename(target)}.${crypto.randomUUID()}.tmp`);
|
|
129
|
+
try {
|
|
130
|
+
const handle = await fsp.open(temp, 'wx', mode);
|
|
131
|
+
try {
|
|
132
|
+
await handle.writeFile(text, 'utf8');
|
|
133
|
+
await handle.chmod(mode);
|
|
134
|
+
await handle.sync();
|
|
135
|
+
}
|
|
136
|
+
finally {
|
|
137
|
+
await handle.close();
|
|
138
|
+
}
|
|
139
|
+
await fsp.rename(temp, target);
|
|
140
|
+
}
|
|
141
|
+
catch (err) {
|
|
142
|
+
await fsp.rm(temp, { force: true });
|
|
143
|
+
throw err;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
//# sourceMappingURL=file.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file.js","sourceRoot":"","sources":["../../../../src/agent-farm/servers/decisions/file.ts"],"names":[],"mappings":"AAAA,kFAAkF;AAClF,gCAAgC;AAChC,EAAE;AACF,mFAAmF;AACnF,qFAAqF;AACrF,oFAAoF;AACpF,qFAAqF;AACrF,sFAAsF;AAEtF,OAAO,MAAM,MAAM,aAAa,CAAC;AACjC,OAAO,EAAE,QAAQ,IAAI,GAAG,EAAE,MAAM,SAAS,CAAC;AAC1C,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACpD,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEpD,MAAM,CAAC,MAAM,sBAAsB,GAAG,kCAAkC,CAAC;AAEzE,uEAAuE;AACvE,MAAM,CAAC,MAAM,uBAAuB,GAAG,KAAK,CAAC;AAkB7C,MAAM,kBAAkB,GAAG,IAAI,GAAG,EAA0D,CAAC;AAE7F,qEAAqE;AACrE,MAAM,CAAC,MAAM,mBAAmB,GAAG,IAAI,eAAe,EAAE,CAAC;AAEzD,SAAS,kBAAkB,CAAC,aAAqB;IAC/C,IAAI,CAAC;QACH,MAAM,KAAK,GAAY,UAAU,CAAC,aAAa,CAAC,CAAC,SAAS,EAAE,aAAa,CAAC;QAC1E,IAAI,KAAK,KAAK,SAAS;YAAE,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,sBAAsB,EAAE,CAAC;QAC3E,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;YACrD,MAAM,IAAI,KAAK,CAAC,2DAA2D,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QACtG,CAAC;QACD,IAAI,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;YAC3B,MAAM,IAAI,KAAK,CAAC,uEAAuE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAClH,CAAC;QACD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;IACnC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,GAAY,EAAE,CAAC;IAC5C,CAAC;AACH,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,uBAAuB,CAAC,aAAqB,EAAE,EAAE,KAAK,EAAsB;IAC1F,MAAM,IAAI,GAAG,kBAAkB,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;IACnD,IAAI,OAA8B,CAAC;IACnC,IAAI,CAAC,KAAK,IAAI,IAAI,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,EAAE,GAAG,uBAAuB,EAAE,CAAC;QACrE,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC;IACzB,CAAC;SAAM,CAAC;QACN,OAAO,GAAG,kBAAkB,CAAC,aAAa,CAAC,CAAC;QAC5C,kBAAkB,CAAC,GAAG,CAAC,aAAa,EAAE,EAAE,EAAE,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;IACrE,CAAC;IACD,IAAI,CAAC,OAAO,CAAC,EAAE;QAAE,MAAM,OAAO,CAAC,KAAK,CAAC;IACrC,OAAO,OAAO,CAAC,IAAI,CAAC;AACtB,CAAC;AAED,sFAAsF;AACtF,KAAK,UAAU,YAAY,CAAC,MAAc;IACxC,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,IAAI,QAAQ,GAAG,MAAM,CAAC;IACtB,SAAS,CAAC;QACR,IAAI,CAAC;YACH,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,GAAG,OAAO,CAAC,CAAC;QAC7D,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;YACtC,IAAK,GAA6B,CAAC,IAAI,KAAK,QAAQ,IAAI,MAAM,KAAK,QAAQ;gBAAE,MAAM,GAAG,CAAC;YACvF,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC;YACzC,QAAQ,GAAG,MAAM,CAAC;QACpB,CAAC;IACH,CAAC;AACH,CAAC;AAED,SAAS,QAAQ,CAAC,IAAY,EAAE,SAAiB;IAC/C,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;IAChD,OAAO,QAAQ,KAAK,EAAE,IAAI,QAAQ,KAAK,IAAI,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,KAAK,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;AACrH,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,aAAqB,EAAE,cAAsB;IACtF,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC;IAC/C,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,cAAc,CAAC,CAAC;IAClD,MAAM,WAAW,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC1E,MAAM,aAAa,GAAG,MAAM,YAAY,CAAC,MAAM,CAAC,CAAC;IACjD,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;QAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,CAAC;IACzF,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,KAAK,CAAC,CAAC,GAA0B,EAAE,EAAE;QAC9E,IAAI,GAAG,CAAC,IAAI,KAAK,QAAQ;YAAE,OAAO,IAAI,CAAC;QACvC,MAAM,GAAG,CAAC;IACZ,CAAC,CAAC,CAAC;IACH,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,KAAK,EAAE,CAAC;AACvF,CAAC;AAED,oGAAoG;AACpG,MAAM,mBAAmB,GAAG,IAAI,GAAG,EAAkB,CAAC;AAEtD;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,aAAqB,EAAE,GAAiB;IACjF,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,oBAAoB,CAAC,aAAa,EAAE,uBAAuB,CAAC,aAAa,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC;QACrH,mBAAmB,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;QAC1C,OAAO,QAAQ,CAAC,MAAM,IAAI,QAAQ,CAAC,MAAM,CAAC;IAC5C,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,OAAO,GAAI,GAAa,CAAC,OAAO,CAAC;QACvC,IAAI,mBAAmB,CAAC,GAAG,CAAC,aAAa,CAAC,KAAK,OAAO,EAAE,CAAC;YACvD,mBAAmB,CAAC,GAAG,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC;YAChD,GAAG,CAAC,MAAM,EAAE,4BAA4B,aAAa,KAAK,OAAO,EAAE,CAAC,CAAC;QACvE,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,MAAc,EAAE,IAAY;IAChE,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,GAAG,MAAM,CAAC;IACpD,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;IACrG,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;QAChD,IAAI,CAAC;YACH,MAAM,MAAM,CAAC,SAAS,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;YACrC,MAAM,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YACzB,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC;QACtB,CAAC;gBAAS,CAAC;YACT,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;QACvB,CAAC;QACD,MAAM,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACjC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QACpC,MAAM,GAAG,CAAC;IACZ,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
export type LineEnding = '' | '\n' | '\r\n';
|
|
2
|
+
export interface SourceLine {
|
|
3
|
+
/** 0-based line number. */
|
|
4
|
+
index: number;
|
|
5
|
+
/** Offset of the line's first character. */
|
|
6
|
+
start: number;
|
|
7
|
+
/** Offset just past the line's last content character (before the line ending). */
|
|
8
|
+
end: number;
|
|
9
|
+
/** The line's terminator ('' only for a final line without a newline). */
|
|
10
|
+
eol: LineEnding;
|
|
11
|
+
/** Line content without its terminator. */
|
|
12
|
+
text: string;
|
|
13
|
+
/** True for content inside a fence and for the fence delimiter lines themselves. */
|
|
14
|
+
fenced: boolean;
|
|
15
|
+
/** True for a fence delimiter line (opening or closing). */
|
|
16
|
+
fenceDelimiter: boolean;
|
|
17
|
+
/** ATX heading level (1–6) for an unfenced heading line, else 0. */
|
|
18
|
+
headingLevel: number;
|
|
19
|
+
/** Heading text (closing `#` sequence and surrounding whitespace removed). */
|
|
20
|
+
headingText: string;
|
|
21
|
+
/** True for an unfenced `**Your word:**` line. */
|
|
22
|
+
yourWord: boolean;
|
|
23
|
+
}
|
|
24
|
+
/** The `**Your word:**` label, as written in the file. */
|
|
25
|
+
export declare const YOUR_WORD_LABEL = "**Your word:**";
|
|
26
|
+
/** Whether `text`, taken as a standalone line, is a fence delimiter. */
|
|
27
|
+
export declare function isFenceLine(text: string): boolean;
|
|
28
|
+
/** Whether `text`, taken as an unfenced line, is an ATX heading. */
|
|
29
|
+
export declare function isHeadingLine(text: string): boolean;
|
|
30
|
+
/** Whether `text`, taken as an unfenced line, is a `**Your word:**` line. */
|
|
31
|
+
export declare function isYourWordLine(text: string): boolean;
|
|
32
|
+
/** Split `text` into classified lines with their original offsets and terminators. */
|
|
33
|
+
export declare function classifyLines(text: string): SourceLine[];
|
|
34
|
+
/** The line ending for inserted text: the file's first terminator (LF when it has none). */
|
|
35
|
+
export declare function detectLineEnding(lines: SourceLine[]): '\n' | '\r\n';
|
|
36
|
+
//# sourceMappingURL=grammar.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"grammar.d.ts","sourceRoot":"","sources":["../../../../src/agent-farm/servers/decisions/grammar.ts"],"names":[],"mappings":"AAgBA,MAAM,MAAM,UAAU,GAAG,EAAE,GAAG,IAAI,GAAG,MAAM,CAAC;AAE5C,MAAM,WAAW,UAAU;IACzB,2BAA2B;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,4CAA4C;IAC5C,KAAK,EAAE,MAAM,CAAC;IACd,mFAAmF;IACnF,GAAG,EAAE,MAAM,CAAC;IACZ,0EAA0E;IAC1E,GAAG,EAAE,UAAU,CAAC;IAChB,2CAA2C;IAC3C,IAAI,EAAE,MAAM,CAAC;IACb,oFAAoF;IACpF,MAAM,EAAE,OAAO,CAAC;IAChB,4DAA4D;IAC5D,cAAc,EAAE,OAAO,CAAC;IACxB,oEAAoE;IACpE,YAAY,EAAE,MAAM,CAAC;IACrB,8EAA8E;IAC9E,WAAW,EAAE,MAAM,CAAC;IACpB,kDAAkD;IAClD,QAAQ,EAAE,OAAO,CAAC;CACnB;AAMD,0DAA0D;AAC1D,eAAO,MAAM,eAAe,mBAAmB,CAAC;AAQhD,wEAAwE;AACxE,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEjD;AAED,oEAAoE;AACpE,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEnD;AAED,6EAA6E;AAC7E,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEpD;AAED,sFAAsF;AACtF,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,EAAE,CAiExD;AAED,4FAA4F;AAC5F,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,UAAU,EAAE,GAAG,IAAI,GAAG,MAAM,CAGnE"}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
// Structural grammar for the decisions file (Spec 1819).
|
|
2
|
+
//
|
|
3
|
+
// One line classifier shared by the parser and the splice, so that what the tab
|
|
4
|
+
// shows and what a write validates can never disagree about structure. It is a
|
|
5
|
+
// subset of CommonMark:
|
|
6
|
+
// - fence lines: up to three leading spaces, then 3+ backticks or tildes. A fence
|
|
7
|
+
// opened by a run of N characters closes at the next line of the same character
|
|
8
|
+
// with at least N characters and nothing but whitespace after it. An unclosed
|
|
9
|
+
// fence runs to end of file.
|
|
10
|
+
// - heading lines: unfenced, up to three leading spaces, 1–6 `#`, then a space or
|
|
11
|
+
// end of line (ATX only; setext underlines are not structural).
|
|
12
|
+
// - Your-word lines: unfenced, up to three leading spaces, then `**Your word:**`.
|
|
13
|
+
//
|
|
14
|
+
// Offsets are string (UTF-16) offsets into the original text, so a splice can
|
|
15
|
+
// insert at an exact position and preserve every other character.
|
|
16
|
+
const FENCE_RE = /^ {0,3}(`{3,}|~{3,})(.*)$/;
|
|
17
|
+
const HEADING_RE = /^ {0,3}(#{1,6})(?:[ \t]+(.*?))?[ \t]*$/;
|
|
18
|
+
const YOUR_WORD_RE = /^ {0,3}\*\*Your word:\*\*/;
|
|
19
|
+
/** The `**Your word:**` label, as written in the file. */
|
|
20
|
+
export const YOUR_WORD_LABEL = '**Your word:**';
|
|
21
|
+
/** Strip an ATX heading's optional closing sequence (` ##`), per CommonMark. */
|
|
22
|
+
function stripClosingHashes(text) {
|
|
23
|
+
if (/^#+$/.test(text))
|
|
24
|
+
return '';
|
|
25
|
+
return text.replace(/[ \t]+#+$/, '').trim();
|
|
26
|
+
}
|
|
27
|
+
/** Whether `text`, taken as a standalone line, is a fence delimiter. */
|
|
28
|
+
export function isFenceLine(text) {
|
|
29
|
+
return FENCE_RE.test(text);
|
|
30
|
+
}
|
|
31
|
+
/** Whether `text`, taken as an unfenced line, is an ATX heading. */
|
|
32
|
+
export function isHeadingLine(text) {
|
|
33
|
+
return HEADING_RE.test(text);
|
|
34
|
+
}
|
|
35
|
+
/** Whether `text`, taken as an unfenced line, is a `**Your word:**` line. */
|
|
36
|
+
export function isYourWordLine(text) {
|
|
37
|
+
return YOUR_WORD_RE.test(text);
|
|
38
|
+
}
|
|
39
|
+
/** Split `text` into classified lines with their original offsets and terminators. */
|
|
40
|
+
export function classifyLines(text) {
|
|
41
|
+
const lines = [];
|
|
42
|
+
let openFence = null;
|
|
43
|
+
let pos = 0;
|
|
44
|
+
let index = 0;
|
|
45
|
+
while (pos < text.length) {
|
|
46
|
+
const nl = text.indexOf('\n', pos);
|
|
47
|
+
let end;
|
|
48
|
+
let eol;
|
|
49
|
+
let next;
|
|
50
|
+
if (nl === -1) {
|
|
51
|
+
end = text.length;
|
|
52
|
+
eol = '';
|
|
53
|
+
next = text.length;
|
|
54
|
+
}
|
|
55
|
+
else if (nl > pos && text[nl - 1] === '\r') {
|
|
56
|
+
end = nl - 1;
|
|
57
|
+
eol = '\r\n';
|
|
58
|
+
next = nl + 1;
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
end = nl;
|
|
62
|
+
eol = '\n';
|
|
63
|
+
next = nl + 1;
|
|
64
|
+
}
|
|
65
|
+
const lineText = text.slice(pos, end);
|
|
66
|
+
let fenced = false;
|
|
67
|
+
let fenceDelimiter = false;
|
|
68
|
+
let headingLevel = 0;
|
|
69
|
+
let headingText = '';
|
|
70
|
+
let yourWord = false;
|
|
71
|
+
const fenceMatch = FENCE_RE.exec(lineText);
|
|
72
|
+
if (openFence) {
|
|
73
|
+
fenced = true;
|
|
74
|
+
if (fenceMatch &&
|
|
75
|
+
fenceMatch[1][0] === openFence.char &&
|
|
76
|
+
fenceMatch[1].length >= openFence.length &&
|
|
77
|
+
fenceMatch[2].trim() === '') {
|
|
78
|
+
fenceDelimiter = true;
|
|
79
|
+
openFence = null;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
else if (fenceMatch && !(fenceMatch[1][0] === '`' && fenceMatch[2].includes('`'))) {
|
|
83
|
+
// A backtick fence's info string may not contain a backtick (CommonMark).
|
|
84
|
+
fenced = true;
|
|
85
|
+
fenceDelimiter = true;
|
|
86
|
+
openFence = { char: fenceMatch[1][0], length: fenceMatch[1].length };
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
const headingMatch = HEADING_RE.exec(lineText);
|
|
90
|
+
if (headingMatch) {
|
|
91
|
+
headingLevel = headingMatch[1].length;
|
|
92
|
+
headingText = stripClosingHashes(headingMatch[2] ?? '');
|
|
93
|
+
}
|
|
94
|
+
else if (YOUR_WORD_RE.test(lineText)) {
|
|
95
|
+
yourWord = true;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
lines.push({ index, start: pos, end, eol, text: lineText, fenced, fenceDelimiter, headingLevel, headingText, yourWord });
|
|
99
|
+
pos = next;
|
|
100
|
+
index++;
|
|
101
|
+
}
|
|
102
|
+
return lines;
|
|
103
|
+
}
|
|
104
|
+
/** The line ending for inserted text: the file's first terminator (LF when it has none). */
|
|
105
|
+
export function detectLineEnding(lines) {
|
|
106
|
+
const first = lines.find(l => l.eol !== '');
|
|
107
|
+
return first?.eol === '\r\n' ? '\r\n' : '\n';
|
|
108
|
+
}
|
|
109
|
+
//# sourceMappingURL=grammar.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"grammar.js","sourceRoot":"","sources":["../../../../src/agent-farm/servers/decisions/grammar.ts"],"names":[],"mappings":"AAAA,yDAAyD;AACzD,EAAE;AACF,gFAAgF;AAChF,+EAA+E;AAC/E,wBAAwB;AACxB,oFAAoF;AACpF,oFAAoF;AACpF,kFAAkF;AAClF,iCAAiC;AACjC,oFAAoF;AACpF,oEAAoE;AACpE,oFAAoF;AACpF,EAAE;AACF,8EAA8E;AAC9E,kEAAkE;AA2BlE,MAAM,QAAQ,GAAG,2BAA2B,CAAC;AAC7C,MAAM,UAAU,GAAG,wCAAwC,CAAC;AAC5D,MAAM,YAAY,GAAG,2BAA2B,CAAC;AAEjD,0DAA0D;AAC1D,MAAM,CAAC,MAAM,eAAe,GAAG,gBAAgB,CAAC;AAEhD,gFAAgF;AAChF,SAAS,kBAAkB,CAAC,IAAY;IACtC,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,EAAE,CAAC;IACjC,OAAO,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;AAC9C,CAAC;AAED,wEAAwE;AACxE,MAAM,UAAU,WAAW,CAAC,IAAY;IACtC,OAAO,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC7B,CAAC;AAED,oEAAoE;AACpE,MAAM,UAAU,aAAa,CAAC,IAAY;IACxC,OAAO,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC/B,CAAC;AAED,6EAA6E;AAC7E,MAAM,UAAU,cAAc,CAAC,IAAY;IACzC,OAAO,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACjC,CAAC;AAED,sFAAsF;AACtF,MAAM,UAAU,aAAa,CAAC,IAAY;IACxC,MAAM,KAAK,GAAiB,EAAE,CAAC;IAC/B,IAAI,SAAS,GAA4C,IAAI,CAAC;IAC9D,IAAI,GAAG,GAAG,CAAC,CAAC;IACZ,IAAI,KAAK,GAAG,CAAC,CAAC;IAEd,OAAO,GAAG,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;QACzB,MAAM,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;QACnC,IAAI,GAAW,CAAC;QAChB,IAAI,GAAe,CAAC;QACpB,IAAI,IAAY,CAAC;QACjB,IAAI,EAAE,KAAK,CAAC,CAAC,EAAE,CAAC;YACd,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC;YAClB,GAAG,GAAG,EAAE,CAAC;YACT,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC;QACrB,CAAC;aAAM,IAAI,EAAE,GAAG,GAAG,IAAI,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;YAC7C,GAAG,GAAG,EAAE,GAAG,CAAC,CAAC;YACb,GAAG,GAAG,MAAM,CAAC;YACb,IAAI,GAAG,EAAE,GAAG,CAAC,CAAC;QAChB,CAAC;aAAM,CAAC;YACN,GAAG,GAAG,EAAE,CAAC;YACT,GAAG,GAAG,IAAI,CAAC;YACX,IAAI,GAAG,EAAE,GAAG,CAAC,CAAC;QAChB,CAAC;QACD,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;QAEtC,IAAI,MAAM,GAAG,KAAK,CAAC;QACnB,IAAI,cAAc,GAAG,KAAK,CAAC;QAC3B,IAAI,YAAY,GAAG,CAAC,CAAC;QACrB,IAAI,WAAW,GAAG,EAAE,CAAC;QACrB,IAAI,QAAQ,GAAG,KAAK,CAAC;QAErB,MAAM,UAAU,GAAG,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC3C,IAAI,SAAS,EAAE,CAAC;YACd,MAAM,GAAG,IAAI,CAAC;YACd,IACE,UAAU;gBACV,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,SAAS,CAAC,IAAI;gBACnC,UAAU,CAAC,CAAC,CAAC,CAAC,MAAM,IAAI,SAAS,CAAC,MAAM;gBACxC,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAC3B,CAAC;gBACD,cAAc,GAAG,IAAI,CAAC;gBACtB,SAAS,GAAG,IAAI,CAAC;YACnB,CAAC;QACH,CAAC;aAAM,IAAI,UAAU,IAAI,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,IAAI,UAAU,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;YACpF,0EAA0E;YAC1E,MAAM,GAAG,IAAI,CAAC;YACd,cAAc,GAAG,IAAI,CAAC;YACtB,SAAS,GAAG,EAAE,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;QACvE,CAAC;aAAM,CAAC;YACN,MAAM,YAAY,GAAG,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YAC/C,IAAI,YAAY,EAAE,CAAC;gBACjB,YAAY,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;gBACtC,WAAW,GAAG,kBAAkB,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;YAC1D,CAAC;iBAAM,IAAI,YAAY,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;gBACvC,QAAQ,GAAG,IAAI,CAAC;YAClB,CAAC;QACH,CAAC;QAED,KAAK,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,cAAc,EAAE,YAAY,EAAE,WAAW,EAAE,QAAQ,EAAE,CAAC,CAAC;QACzH,GAAG,GAAG,IAAI,CAAC;QACX,KAAK,EAAE,CAAC;IACV,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED,4FAA4F;AAC5F,MAAM,UAAU,gBAAgB,CAAC,KAAmB;IAClD,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,KAAK,EAAE,CAAC,CAAC;IAC5C,OAAO,KAAK,EAAE,GAAG,KAAK,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC;AAC/C,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { RulingRequest } from './splice.js';
|
|
2
|
+
/** Tell the hub architect `message`. May throw; the route logs the failure. */
|
|
3
|
+
export type RulingNotifier = (message: string) => Promise<void>;
|
|
4
|
+
/**
|
|
5
|
+
* The notice for a ruling the splice accepted: `RULED <id>: <word>`, or
|
|
6
|
+
* `QUESTION <id>:` when no word was chosen, with the trimmed comment on the lines after it.
|
|
7
|
+
* The comment is trimmed and split exactly as `spliceRuling` does, so the notice carries
|
|
8
|
+
* the lines that were written to the file.
|
|
9
|
+
*/
|
|
10
|
+
export declare function rulingNotice(ruling: RulingRequest): string;
|
|
11
|
+
//# sourceMappingURL=notice.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"notice.d.ts","sourceRoot":"","sources":["../../../../src/agent-farm/servers/decisions/notice.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAEjD,+EAA+E;AAC/E,MAAM,MAAM,cAAc,GAAG,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;AAEhE;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,aAAa,GAAG,MAAM,CAI1D"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
// The hub architect's notice of a Decisions-tab ruling (#1828).
|
|
2
|
+
//
|
|
3
|
+
// Once a ruling is written, Tower tells the workspace's hub architect through the
|
|
4
|
+
// mailbox, so the hub need not watch the file for it. The file stays the source of
|
|
5
|
+
// truth: the notice is best-effort, and a ruling typed into the file by hand still
|
|
6
|
+
// reaches the hub only when it scans the file.
|
|
7
|
+
/**
|
|
8
|
+
* The notice for a ruling the splice accepted: `RULED <id>: <word>`, or
|
|
9
|
+
* `QUESTION <id>:` when no word was chosen, with the trimmed comment on the lines after it.
|
|
10
|
+
* The comment is trimmed and split exactly as `spliceRuling` does, so the notice carries
|
|
11
|
+
* the lines that were written to the file.
|
|
12
|
+
*/
|
|
13
|
+
export function rulingNotice(ruling) {
|
|
14
|
+
const head = ruling.word ? `RULED ${ruling.id}: ${ruling.word}` : `QUESTION ${ruling.id}:`;
|
|
15
|
+
const comment = (ruling.comment ?? '').trim().split(/\r\n|\r|\n/).join('\n');
|
|
16
|
+
return comment ? `${head}\n${comment}` : head;
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=notice.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"notice.js","sourceRoot":"","sources":["../../../../src/agent-farm/servers/decisions/notice.ts"],"names":[],"mappings":"AAAA,gEAAgE;AAChE,EAAE;AACF,kFAAkF;AAClF,mFAAmF;AACnF,mFAAmF;AACnF,+CAA+C;AAO/C;;;;;GAKG;AACH,MAAM,UAAU,YAAY,CAAC,MAAqB;IAChD,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,MAAM,CAAC,EAAE,KAAK,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,YAAY,MAAM,CAAC,EAAE,GAAG,CAAC;IAC3F,MAAM,OAAO,GAAG,CAAC,MAAM,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC7E,OAAO,OAAO,CAAC,CAAC,CAAC,GAAG,IAAI,KAAK,OAAO,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;AAChD,CAAC"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { DecisionItem, DecisionOption, DecisionsDocument, DecisionsFileProblem } from '@cluesmith/codev-types';
|
|
2
|
+
import { type SourceLine } from './grammar.js';
|
|
3
|
+
export interface ParsedItem extends DecisionItem {
|
|
4
|
+
/** Line index of the item's `###` heading. */
|
|
5
|
+
headingLine: number;
|
|
6
|
+
/** Line index just past the item's last line. */
|
|
7
|
+
endLine: number;
|
|
8
|
+
/** Offset of the heading line's first character. */
|
|
9
|
+
start: number;
|
|
10
|
+
/** Offset just past the item's last character (its final line ending included). */
|
|
11
|
+
end: number;
|
|
12
|
+
/** Line indices of the item's `**Your word:**` lines. */
|
|
13
|
+
yourWordLines: number[];
|
|
14
|
+
}
|
|
15
|
+
export interface ParsedDecisions {
|
|
16
|
+
lines: SourceLine[];
|
|
17
|
+
/** Line ending for inserted text: the file's own. */
|
|
18
|
+
eol: '\n' | '\r\n';
|
|
19
|
+
items: ParsedItem[];
|
|
20
|
+
ruledMarkdown: string;
|
|
21
|
+
problems: DecisionsFileProblem[];
|
|
22
|
+
version: string;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Options from a `**Your word:**` line. An option starts at a backticked span at the
|
|
26
|
+
* start of the text after the label, or at a backticked span immediately preceded by
|
|
27
|
+
* ` / `. Its description is the text after its `=`, if any, up to the next ` / ` that
|
|
28
|
+
* is followed by a backtick, or end of line. Any other ` / ` is part of the
|
|
29
|
+
* description. Text that is not an option, or not after an `=`, is not read.
|
|
30
|
+
*/
|
|
31
|
+
export declare function parseOptions(yourWordLineText: string): DecisionOption[];
|
|
32
|
+
/** Parse the decisions file's text into its read model. */
|
|
33
|
+
export declare function parseDecisions(text: string): ParsedDecisions;
|
|
34
|
+
/** Project the parse onto the wire document served to the dashboard. */
|
|
35
|
+
export declare function toDecisionsDocument(parsed: ParsedDecisions, path: string): DecisionsDocument;
|
|
36
|
+
//# sourceMappingURL=parse.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parse.d.ts","sourceRoot":"","sources":["../../../../src/agent-farm/servers/decisions/parse.ts"],"names":[],"mappings":"AAyBA,OAAO,KAAK,EACV,YAAY,EAEZ,cAAc,EAGd,iBAAiB,EACjB,oBAAoB,EACrB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAoD,KAAK,UAAU,EAAE,MAAM,cAAc,CAAC;AAGjG,MAAM,WAAW,UAAW,SAAQ,YAAY;IAC9C,8CAA8C;IAC9C,WAAW,EAAE,MAAM,CAAC;IACpB,iDAAiD;IACjD,OAAO,EAAE,MAAM,CAAC;IAChB,oDAAoD;IACpD,KAAK,EAAE,MAAM,CAAC;IACd,mFAAmF;IACnF,GAAG,EAAE,MAAM,CAAC;IACZ,yDAAyD;IACzD,aAAa,EAAE,MAAM,EAAE,CAAC;CACzB;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,UAAU,EAAE,CAAC;IACpB,qDAAqD;IACrD,GAAG,EAAE,IAAI,GAAG,MAAM,CAAC;IACnB,KAAK,EAAE,UAAU,EAAE,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,oBAAoB,EAAE,CAAC;IACjC,OAAO,EAAE,MAAM,CAAC;CACjB;AA4DD;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,gBAAgB,EAAE,MAAM,GAAG,cAAc,EAAE,CAuBvE;AAmGD,2DAA2D;AAC3D,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,eAAe,CAiD5D;AA+DD,wEAAwE;AACxE,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,eAAe,EAAE,IAAI,EAAE,MAAM,GAAG,iBAAiB,CAmB5F"}
|