@cluesmith/codev 3.3.5 → 3.3.7
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-r3bZzLmX.css → index-BjcqV9Vv.css} +1 -1
- package/dashboard-dist/assets/{index-BuflRUi6.js → index-b7GnZV2i.js} +55 -55
- 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.map +1 -1
- package/dist/agent-farm/commands/send.js +13 -18
- 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 +51 -18
- 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-prefix.d.ts +10 -0
- package/dist/agent-farm/lib/ide-prefix.d.ts.map +1 -0
- package/dist/agent-farm/lib/ide-prefix.js +13 -0
- package/dist/agent-farm/lib/ide-prefix.js.map +1 -0
- package/dist/agent-farm/lib/ide-record.d.ts +20 -3
- package/dist/agent-farm/lib/ide-record.d.ts.map +1 -1
- package/dist/agent-farm/lib/ide-record.js +34 -3
- 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/parse.d.ts.map +1 -1
- package/dist/agent-farm/servers/decisions/parse.js +45 -15
- package/dist/agent-farm/servers/decisions/parse.js.map +1 -1
- package/dist/agent-farm/servers/decisions/stamp.d.ts +6 -2
- package/dist/agent-farm/servers/decisions/stamp.d.ts.map +1 -1
- package/dist/agent-farm/servers/decisions/stamp.js +53 -29
- package/dist/agent-farm/servers/decisions/stamp.js.map +1 -1
- 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-forward.d.ts +57 -5
- package/dist/agent-farm/servers/ide-forward.d.ts.map +1 -1
- package/dist/agent-farm/servers/ide-forward.js +263 -31
- package/dist/agent-farm/servers/ide-forward.js.map +1 -1
- 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 +151 -52
- package/dist/agent-farm/servers/ide-server.js.map +1 -1
- package/dist/agent-farm/servers/overview.d.ts +27 -1
- package/dist/agent-farm/servers/overview.d.ts.map +1 -1
- package/dist/agent-farm/servers/overview.js +184 -31
- 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 +149 -15
- 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/servers/tower-websocket.d.ts.map +1 -1
- package/dist/agent-farm/servers/tower-websocket.js +11 -7
- package/dist/agent-farm/servers/tower-websocket.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/server-utils.d.ts +54 -19
- package/dist/agent-farm/utils/server-utils.d.ts.map +1 -1
- package/dist/agent-farm/utils/server-utils.js +144 -27
- package/dist/agent-farm/utils/server-utils.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.map +1 -1
- package/dist/commands/consult/index.js +14 -1
- 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/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/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 +22 -1
- package/dist/lib/agent-env.d.ts.map +1 -1
- package/dist/lib/agent-env.js +27 -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/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 +36 -0
- package/skeleton/.claude/skills/codev/SKILL.md +18 -2
- package/skeleton/.claude/skills/update-arch-docs/SKILL.md +28 -2
- package/skeleton/.codex/skills/afx/SKILL.md +36 -0
- package/skeleton/.codex/skills/codev/SKILL.md +18 -2
- package/skeleton/.codex/skills/update-arch-docs/SKILL.md +28 -2
- package/skeleton/resources/commands/agent-farm.md +139 -0
- package/skeleton/resources/commands/codev.md +47 -0
- 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 +1 -0
- package/templates/tower.html +78 -3
- package/dashboard-dist/assets/index-BuflRUi6.js.map +0 -1
|
@@ -14,9 +14,10 @@
|
|
|
14
14
|
*/
|
|
15
15
|
import type { Builder } from '../types.js';
|
|
16
16
|
/**
|
|
17
|
-
* Find a builder by issue number. Local state first, then Tower
|
|
17
|
+
* Find a builder by issue number or tracker key. Local state first, then Tower
|
|
18
|
+
* fallback. Keys match case-insensitively (role ids are lower-cased).
|
|
18
19
|
*/
|
|
19
|
-
export declare function findBuilderByIssue(issueNumber: number): Builder | null;
|
|
20
|
+
export declare function findBuilderByIssue(issueNumber: number | string): Builder | null;
|
|
20
21
|
/**
|
|
21
22
|
* Find a builder by ID. Tries an exact getBuilder(id) lookup first, then
|
|
22
23
|
* resolveAgentName against local builders, then resolveAgentName against
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"builder-lookup.d.ts","sourceRoot":"","sources":["../../../src/agent-farm/lib/builder-lookup.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"builder-lookup.d.ts","sourceRoot":"","sources":["../../../src/agent-farm/lib/builder-lookup.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAS3C;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,CAW/E;AAkBD;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,GAAG,IAAI,CA4B1D"}
|
|
@@ -18,24 +18,39 @@ import { getConfig } from '../utils/config.js';
|
|
|
18
18
|
import { normalizeWorkspacePath } from '../servers/tower-utils.js';
|
|
19
19
|
import { getGlobalDb } from '../db/index.js';
|
|
20
20
|
import { resolveAgentName } from '@cluesmith/codev-sdk/agent-names';
|
|
21
|
+
import { ISSUE_KEY_SOURCE, canonicalIssueId, sameIssueId } from '../../lib/issue-id.js';
|
|
21
22
|
/**
|
|
22
|
-
* Find a builder by issue number. Local state first, then Tower
|
|
23
|
+
* Find a builder by issue number or tracker key. Local state first, then Tower
|
|
24
|
+
* fallback. Keys match case-insensitively (role ids are lower-cased).
|
|
23
25
|
*/
|
|
24
26
|
export function findBuilderByIssue(issueNumber) {
|
|
25
27
|
// Issue #1118: scope to this workspace (matches loadTowerBuilderRows below),
|
|
26
28
|
// now that builders from every workspace share one global.db.
|
|
27
29
|
const workspaceRoot = normalizeWorkspacePath(getConfig().workspaceRoot);
|
|
28
|
-
const local = getBuilders(workspaceRoot).find((b) => b.issueNumber
|
|
30
|
+
const local = getBuilders(workspaceRoot).find((b) => sameIssueId(b.issueNumber, issueNumber));
|
|
29
31
|
if (local)
|
|
30
32
|
return local;
|
|
31
33
|
const rows = loadTowerBuilderRows();
|
|
32
|
-
const
|
|
33
|
-
const match = rows.find((r) =>
|
|
34
|
-
const m = r.role_id.match(/-bugfix-(\d+)/);
|
|
35
|
-
return m !== null && m[1] === stripped;
|
|
36
|
-
});
|
|
34
|
+
const wanted = String(issueNumber).toLowerCase();
|
|
35
|
+
const match = rows.find((r) => bugfixIssueOfRole(r.role_id) === wanted);
|
|
37
36
|
return match ? towerRowToBuilder(match) : null;
|
|
38
37
|
}
|
|
38
|
+
/** The issue segment of a bugfix role id (`builder-bugfix-42`, `builder-bugfix-eng-12`), lower-cased. */
|
|
39
|
+
function bugfixIssueOfRole(roleId) {
|
|
40
|
+
const m = roleId.match(BUGFIX_ROLE_ISSUE);
|
|
41
|
+
if (!m)
|
|
42
|
+
return null;
|
|
43
|
+
return m[1].toLowerCase();
|
|
44
|
+
}
|
|
45
|
+
const BUGFIX_ROLE_ISSUE = new RegExp(`-bugfix-(\\d+|${ISSUE_KEY_SOURCE})`, 'i');
|
|
46
|
+
/** A role id's issue segment as a Builder issue: numbers as numbers, keys canonicalized. */
|
|
47
|
+
function issueFromRoleSegment(segment) {
|
|
48
|
+
if (segment === null)
|
|
49
|
+
return undefined;
|
|
50
|
+
if (/^\d+$/.test(segment))
|
|
51
|
+
return Number(segment);
|
|
52
|
+
return canonicalIssueId(segment);
|
|
53
|
+
}
|
|
39
54
|
/**
|
|
40
55
|
* Find a builder by ID. Tries an exact getBuilder(id) lookup first, then
|
|
41
56
|
* resolveAgentName against local builders, then resolveAgentName against
|
|
@@ -94,7 +109,7 @@ function loadTowerBuilderRows() {
|
|
|
94
109
|
}
|
|
95
110
|
function towerRowToBuilder(row) {
|
|
96
111
|
const isBugfix = row.role_id.includes('-bugfix-');
|
|
97
|
-
const
|
|
112
|
+
const issue = isBugfix ? bugfixIssueOfRole(row.role_id) : null;
|
|
98
113
|
return {
|
|
99
114
|
id: row.role_id,
|
|
100
115
|
name: row.label ?? row.role_id,
|
|
@@ -103,7 +118,7 @@ function towerRowToBuilder(row) {
|
|
|
103
118
|
worktree: row.cwd ?? '',
|
|
104
119
|
branch: '',
|
|
105
120
|
type: isBugfix ? 'bugfix' : 'spec',
|
|
106
|
-
issueNumber:
|
|
121
|
+
issueNumber: issueFromRoleSegment(issue),
|
|
107
122
|
};
|
|
108
123
|
}
|
|
109
124
|
//# sourceMappingURL=builder-lookup.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"builder-lookup.js","sourceRoot":"","sources":["../../../src/agent-farm/lib/builder-lookup.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAGH,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AACtD,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,OAAO,EAAE,sBAAsB,EAAE,MAAM,2BAA2B,CAAC;AACnE,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC7C,OAAO,EAAE,gBAAgB,EAAE,MAAM,kCAAkC,CAAC;
|
|
1
|
+
{"version":3,"file":"builder-lookup.js","sourceRoot":"","sources":["../../../src/agent-farm/lib/builder-lookup.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tower-owned IDE extensions directory and the embedded sidebar install (Spec 1789).
|
|
3
|
+
*
|
|
4
|
+
* The codev package ships the sidebar vsix in `ide-extension/`. Before Tower
|
|
5
|
+
* spawns a Codev IDE server it makes sure `~/.agent-farm/ide-extensions` holds
|
|
6
|
+
* that sidebar at exactly the embedded version, using the server's own CLI
|
|
7
|
+
* (`--install-extension <vsix> --force --extensions-dir <dir>`). Only the
|
|
8
|
+
* sidebar is touched: other extensions in the directory are left alone.
|
|
9
|
+
*/
|
|
10
|
+
import { type LogFn } from './ide-version.js';
|
|
11
|
+
/**
|
|
12
|
+
* Embedded sidebar layout inside the installed package. Mirrors
|
|
13
|
+
* `scripts/ide-extension-manifest.mjs`, which writes it at build time but is
|
|
14
|
+
* not shipped; a parity test keeps the two in step.
|
|
15
|
+
*/
|
|
16
|
+
export declare const IDE_EXTENSION_DIR = "ide-extension";
|
|
17
|
+
export declare const IDE_EXTENSION_VSIX = "codev-vscode.vsix";
|
|
18
|
+
export declare const IDE_EXTENSION_MANIFEST = "manifest.json";
|
|
19
|
+
/** Directory name of the Tower-owned extensions directory under AGENT_FARM_DIR. */
|
|
20
|
+
export declare const IDE_EXTENSIONS_DIRNAME = "ide-extensions";
|
|
21
|
+
export declare function getIdeExtensionsDir(): string;
|
|
22
|
+
/** Thrown when the extensions directory exists but is unsafe to use. */
|
|
23
|
+
export declare class IdeExtensionsDirError extends Error {
|
|
24
|
+
constructor(dir: string, problem: string);
|
|
25
|
+
}
|
|
26
|
+
export interface EnsureIdeExtensionsDirOptions {
|
|
27
|
+
/** Expected owner; tests override it because they cannot chown. */
|
|
28
|
+
uid?: number;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Create the extensions directory owner-only (0700), or validate an existing
|
|
32
|
+
* one: it must be a real directory, not a symlink, owned by the current user.
|
|
33
|
+
*/
|
|
34
|
+
export declare function ensureIdeExtensionsDir(dir: string, opts?: EnsureIdeExtensionsDirOptions): void;
|
|
35
|
+
export interface EmbeddedSidebar {
|
|
36
|
+
vsixPath: string;
|
|
37
|
+
id: string;
|
|
38
|
+
version: string;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* The sidebar vsix embedded in the installed package, or null when the vsix or
|
|
42
|
+
* its manifest is missing or unreadable (a source checkout without a package build).
|
|
43
|
+
*/
|
|
44
|
+
export declare function locateEmbeddedSidebar(embeddedDir?: string): EmbeddedSidebar | null;
|
|
45
|
+
/**
|
|
46
|
+
* The version of extension `id` listed in the directory's `extensions.json`,
|
|
47
|
+
* matching the identifier case-insensitively as VS Code does. Null when the
|
|
48
|
+
* index is absent, unreadable or does not list the extension.
|
|
49
|
+
*/
|
|
50
|
+
export declare function readInstalledExtensionVersion(dir: string, id: string): string | null;
|
|
51
|
+
/** Thrown when the server CLI fails to install the embedded sidebar. */
|
|
52
|
+
export declare class IdeSidebarInstallError extends Error {
|
|
53
|
+
constructor(message: string);
|
|
54
|
+
}
|
|
55
|
+
export interface EnsureSidebarInstalledOptions {
|
|
56
|
+
/** Defaults to `getIdeExtensionsDir()`. */
|
|
57
|
+
extensionsDir?: string;
|
|
58
|
+
/** Directory holding the embedded vsix and manifest; defaults to the installed package's. */
|
|
59
|
+
embeddedDir?: string;
|
|
60
|
+
timeoutMs?: number;
|
|
61
|
+
env?: Record<string, string>;
|
|
62
|
+
log?: LogFn;
|
|
63
|
+
/** Passed through to `ensureIdeExtensionsDir`. */
|
|
64
|
+
uid?: number;
|
|
65
|
+
}
|
|
66
|
+
export interface SidebarInstallResult {
|
|
67
|
+
outcome: 'skipped' | 'installed' | 'missing-vsix';
|
|
68
|
+
/** The embedded sidebar version; null when the vsix is missing. */
|
|
69
|
+
version: string | null;
|
|
70
|
+
/** The version indexed before this call; null when none was. */
|
|
71
|
+
previousVersion: string | null;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Make the extensions directory hold the embedded sidebar at exactly the
|
|
75
|
+
* embedded version. Skips without a subprocess when that version is already
|
|
76
|
+
* indexed; otherwise installs with `--force` so an older or newer copy is
|
|
77
|
+
* replaced. Throws an `IdeSidebarInstallError` when the install fails, times
|
|
78
|
+
* out, or leaves the index without the embedded version. A missing embedded
|
|
79
|
+
* vsix is only a warning: the IDE works without the sidebar.
|
|
80
|
+
*/
|
|
81
|
+
export declare function ensureSidebarInstalled(serverPath: string, opts?: EnsureSidebarInstalledOptions): Promise<SidebarInstallResult>;
|
|
82
|
+
//# sourceMappingURL=ide-extensions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ide-extensions.d.ts","sourceRoot":"","sources":["../../../src/agent-farm/lib/ide-extensions.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAMH,OAAO,EAGL,KAAK,KAAK,EAGX,MAAM,kBAAkB,CAAC;AAE1B;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,kBAAkB,CAAC;AACjD,eAAO,MAAM,kBAAkB,sBAAsB,CAAC;AACtD,eAAO,MAAM,sBAAsB,kBAAkB,CAAC;AAEtD,mFAAmF;AACnF,eAAO,MAAM,sBAAsB,mBAAmB,CAAC;AAUvD,wBAAgB,mBAAmB,IAAI,MAAM,CAE5C;AAED,wEAAwE;AACxE,qBAAa,qBAAsB,SAAQ,KAAK;gBAClC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM;CAIzC;AAED,MAAM,WAAW,6BAA6B;IAC5C,mEAAmE;IACnE,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,GAAE,6BAAkC,GAAG,IAAI,CAmBlG;AAUD,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,WAAW,GAAE,MAA6B,GAAG,eAAe,GAAG,IAAI,CAcxG;AAED;;;;GAIG;AACH,wBAAgB,6BAA6B,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAiBpF;AAED,wEAAwE;AACxE,qBAAa,sBAAuB,SAAQ,KAAK;gBACnC,OAAO,EAAE,MAAM;CAI5B;AAOD,MAAM,WAAW,6BAA6B;IAC5C,2CAA2C;IAC3C,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,6FAA6F;IAC7F,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,GAAG,CAAC,EAAE,KAAK,CAAC;IACZ,kDAAkD;IAClD,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,SAAS,GAAG,WAAW,GAAG,cAAc,CAAC;IAClD,mEAAmE;IACnE,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,gEAAgE;IAChE,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;CAChC;AAMD;;;;;;;GAOG;AACH,wBAAsB,sBAAsB,CAC1C,UAAU,EAAE,MAAM,EAClB,IAAI,GAAE,6BAAkC,GACvC,OAAO,CAAC,oBAAoB,CAAC,CAkC/B"}
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tower-owned IDE extensions directory and the embedded sidebar install (Spec 1789).
|
|
3
|
+
*
|
|
4
|
+
* The codev package ships the sidebar vsix in `ide-extension/`. Before Tower
|
|
5
|
+
* spawns a Codev IDE server it makes sure `~/.agent-farm/ide-extensions` holds
|
|
6
|
+
* that sidebar at exactly the embedded version, using the server's own CLI
|
|
7
|
+
* (`--install-extension <vsix> --force --extensions-dir <dir>`). Only the
|
|
8
|
+
* sidebar is touched: other extensions in the directory are left alone.
|
|
9
|
+
*/
|
|
10
|
+
import { existsSync, lstatSync, mkdirSync, chmodSync, readFileSync } from 'node:fs';
|
|
11
|
+
import { dirname, resolve } from 'node:path';
|
|
12
|
+
import { fileURLToPath } from 'node:url';
|
|
13
|
+
import { AGENT_FARM_DIR } from './tower-client.js';
|
|
14
|
+
import { IDE_INSTALL_TIMEOUT_MS, IdeServerCommandError, buildIdeServerEnv, runIdeServerCommand, } from './ide-version.js';
|
|
15
|
+
/**
|
|
16
|
+
* Embedded sidebar layout inside the installed package. Mirrors
|
|
17
|
+
* `scripts/ide-extension-manifest.mjs`, which writes it at build time but is
|
|
18
|
+
* not shipped; a parity test keeps the two in step.
|
|
19
|
+
*/
|
|
20
|
+
export const IDE_EXTENSION_DIR = 'ide-extension';
|
|
21
|
+
export const IDE_EXTENSION_VSIX = 'codev-vscode.vsix';
|
|
22
|
+
export const IDE_EXTENSION_MANIFEST = 'manifest.json';
|
|
23
|
+
/** Directory name of the Tower-owned extensions directory under AGENT_FARM_DIR. */
|
|
24
|
+
export const IDE_EXTENSIONS_DIRNAME = 'ide-extensions';
|
|
25
|
+
/** VS Code's index of the extensions installed in an extensions directory. */
|
|
26
|
+
const EXTENSIONS_INDEX = 'extensions.json';
|
|
27
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
28
|
+
/** The installed package's `ide-extension/` (the same layout `dashboard-dist` uses). */
|
|
29
|
+
const DEFAULT_EMBEDDED_DIR = resolve(__dirname, '../../..', IDE_EXTENSION_DIR);
|
|
30
|
+
export function getIdeExtensionsDir() {
|
|
31
|
+
return resolve(AGENT_FARM_DIR, IDE_EXTENSIONS_DIRNAME);
|
|
32
|
+
}
|
|
33
|
+
/** Thrown when the extensions directory exists but is unsafe to use. */
|
|
34
|
+
export class IdeExtensionsDirError extends Error {
|
|
35
|
+
constructor(dir, problem) {
|
|
36
|
+
super(`IDE extensions directory ${dir} ${problem}; remove or fix it and retry`);
|
|
37
|
+
this.name = 'IdeExtensionsDirError';
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Create the extensions directory owner-only (0700), or validate an existing
|
|
42
|
+
* one: it must be a real directory, not a symlink, owned by the current user.
|
|
43
|
+
*/
|
|
44
|
+
export function ensureIdeExtensionsDir(dir, opts = {}) {
|
|
45
|
+
if (!existsSync(dir) && !isDanglingSymlink(dir)) {
|
|
46
|
+
mkdirSync(dir, { recursive: true, mode: 0o700 });
|
|
47
|
+
// mkdir's mode is filtered by the umask; set it explicitly.
|
|
48
|
+
chmodSync(dir, 0o700);
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
const stat = lstatSync(dir);
|
|
52
|
+
if (stat.isSymbolicLink()) {
|
|
53
|
+
throw new IdeExtensionsDirError(dir, 'is a symlink');
|
|
54
|
+
}
|
|
55
|
+
if (!stat.isDirectory()) {
|
|
56
|
+
throw new IdeExtensionsDirError(dir, 'is not a directory');
|
|
57
|
+
}
|
|
58
|
+
const uid = opts.uid ?? process.getuid?.();
|
|
59
|
+
if (uid !== undefined && stat.uid !== uid) {
|
|
60
|
+
throw new IdeExtensionsDirError(dir, `is owned by uid ${stat.uid}, not the current user (uid ${uid})`);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
function isDanglingSymlink(path) {
|
|
64
|
+
try {
|
|
65
|
+
return lstatSync(path).isSymbolicLink();
|
|
66
|
+
}
|
|
67
|
+
catch {
|
|
68
|
+
return false;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* The sidebar vsix embedded in the installed package, or null when the vsix or
|
|
73
|
+
* its manifest is missing or unreadable (a source checkout without a package build).
|
|
74
|
+
*/
|
|
75
|
+
export function locateEmbeddedSidebar(embeddedDir = DEFAULT_EMBEDDED_DIR) {
|
|
76
|
+
const vsixPath = resolve(embeddedDir, IDE_EXTENSION_VSIX);
|
|
77
|
+
if (!existsSync(vsixPath))
|
|
78
|
+
return null;
|
|
79
|
+
let manifest;
|
|
80
|
+
try {
|
|
81
|
+
manifest = JSON.parse(readFileSync(resolve(embeddedDir, IDE_EXTENSION_MANIFEST), 'utf8'));
|
|
82
|
+
}
|
|
83
|
+
catch {
|
|
84
|
+
return null;
|
|
85
|
+
}
|
|
86
|
+
if (typeof manifest !== 'object' || manifest === null)
|
|
87
|
+
return null;
|
|
88
|
+
const { id, version } = manifest;
|
|
89
|
+
if (typeof id !== 'string' || id === '' || typeof version !== 'string' || version === '')
|
|
90
|
+
return null;
|
|
91
|
+
return { vsixPath, id, version };
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* The version of extension `id` listed in the directory's `extensions.json`,
|
|
95
|
+
* matching the identifier case-insensitively as VS Code does. Null when the
|
|
96
|
+
* index is absent, unreadable or does not list the extension.
|
|
97
|
+
*/
|
|
98
|
+
export function readInstalledExtensionVersion(dir, id) {
|
|
99
|
+
let index;
|
|
100
|
+
try {
|
|
101
|
+
index = JSON.parse(readFileSync(resolve(dir, EXTENSIONS_INDEX), 'utf8'));
|
|
102
|
+
}
|
|
103
|
+
catch {
|
|
104
|
+
return null;
|
|
105
|
+
}
|
|
106
|
+
if (!Array.isArray(index))
|
|
107
|
+
return null;
|
|
108
|
+
const wanted = id.toLowerCase();
|
|
109
|
+
for (const entry of index) {
|
|
110
|
+
if (typeof entry !== 'object' || entry === null)
|
|
111
|
+
continue;
|
|
112
|
+
const { identifier, version } = entry;
|
|
113
|
+
if (typeof identifier?.id !== 'string' || identifier.id.toLowerCase() !== wanted)
|
|
114
|
+
continue;
|
|
115
|
+
if (typeof version === 'string')
|
|
116
|
+
return version;
|
|
117
|
+
}
|
|
118
|
+
return null;
|
|
119
|
+
}
|
|
120
|
+
/** Thrown when the server CLI fails to install the embedded sidebar. */
|
|
121
|
+
export class IdeSidebarInstallError extends Error {
|
|
122
|
+
constructor(message) {
|
|
123
|
+
super(message);
|
|
124
|
+
this.name = 'IdeSidebarInstallError';
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
/** Likely cause of a refused install, appended only when the CLI itself failed. */
|
|
128
|
+
const BUILT_IN_SIDEBAR_HINT = 'The usual cause is a Codev IDE server that bundles codev-vscode as a built-in extension, ' +
|
|
129
|
+
'which refuses the install; use a server package that does not ship the sidebar';
|
|
130
|
+
function defaultLog(level, message) {
|
|
131
|
+
console.warn(`[${level}] ${message}`);
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Make the extensions directory hold the embedded sidebar at exactly the
|
|
135
|
+
* embedded version. Skips without a subprocess when that version is already
|
|
136
|
+
* indexed; otherwise installs with `--force` so an older or newer copy is
|
|
137
|
+
* replaced. Throws an `IdeSidebarInstallError` when the install fails, times
|
|
138
|
+
* out, or leaves the index without the embedded version. A missing embedded
|
|
139
|
+
* vsix is only a warning: the IDE works without the sidebar.
|
|
140
|
+
*/
|
|
141
|
+
export async function ensureSidebarInstalled(serverPath, opts = {}) {
|
|
142
|
+
const dir = opts.extensionsDir ?? getIdeExtensionsDir();
|
|
143
|
+
const log = opts.log ?? defaultLog;
|
|
144
|
+
ensureIdeExtensionsDir(dir, { uid: opts.uid });
|
|
145
|
+
const sidebar = locateEmbeddedSidebar(opts.embeddedDir);
|
|
146
|
+
if (sidebar === null) {
|
|
147
|
+
log('WARN', 'Embedded Codev sidebar not found (run the package build); the IDE will start without it');
|
|
148
|
+
return { outcome: 'missing-vsix', version: null, previousVersion: null };
|
|
149
|
+
}
|
|
150
|
+
const previousVersion = readInstalledExtensionVersion(dir, sidebar.id);
|
|
151
|
+
if (previousVersion === sidebar.version) {
|
|
152
|
+
return { outcome: 'skipped', version: sidebar.version, previousVersion };
|
|
153
|
+
}
|
|
154
|
+
const timeoutMs = opts.timeoutMs ?? IDE_INSTALL_TIMEOUT_MS;
|
|
155
|
+
const args = ['--install-extension', sidebar.vsixPath, '--force', '--extensions-dir', dir];
|
|
156
|
+
log('INFO', `Installing Codev sidebar ${sidebar.version} into ${dir} (indexed: ${previousVersion ?? 'none'})`);
|
|
157
|
+
try {
|
|
158
|
+
await runIdeServerCommand(serverPath, args, { timeoutMs, env: opts.env ?? buildIdeServerEnv() });
|
|
159
|
+
}
|
|
160
|
+
catch (failure) {
|
|
161
|
+
if (!(failure instanceof IdeServerCommandError))
|
|
162
|
+
throw failure;
|
|
163
|
+
throw new IdeSidebarInstallError(describeInstallFailure(serverPath, sidebar, failure));
|
|
164
|
+
}
|
|
165
|
+
const installedVersion = readInstalledExtensionVersion(dir, sidebar.id);
|
|
166
|
+
if (installedVersion !== sidebar.version) {
|
|
167
|
+
throw new IdeSidebarInstallError(`IDE server at ${serverPath} reported success installing the Codev sidebar ${sidebar.version}, ` +
|
|
168
|
+
`but ${dir} lists ${installedVersion ?? 'no version'}`);
|
|
169
|
+
}
|
|
170
|
+
return { outcome: 'installed', version: sidebar.version, previousVersion };
|
|
171
|
+
}
|
|
172
|
+
function describeInstallFailure(serverPath, sidebar, failure) {
|
|
173
|
+
let detail = `IDE server at ${serverPath} failed to install the Codev sidebar ${sidebar.version} (${failure.message})`;
|
|
174
|
+
if (failure.stderr !== '') {
|
|
175
|
+
detail = `${detail}: ${failure.stderr}`;
|
|
176
|
+
}
|
|
177
|
+
return `${detail}. ${BUILT_IN_SIDEBAR_HINT}`;
|
|
178
|
+
}
|
|
179
|
+
//# sourceMappingURL=ide-extensions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ide-extensions.js","sourceRoot":"","sources":["../../../src/agent-farm/lib/ide-extensions.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The IDE forward prefix (Issue #1668 §D1) and its matcher. Dependency-free on
|
|
3
|
+
* purpose: the auth seam (`utils/server-utils.ts`) imports it, and it must stay
|
|
4
|
+
* a light leaf (Issue #1869). `ide-record.ts` re-exports both.
|
|
5
|
+
*/
|
|
6
|
+
/** The fixed Tower prefix that routes to the IDE server (Issue #1668 §D1). */
|
|
7
|
+
export declare const IDE_DEFAULT_PREFIX = "/ide/";
|
|
8
|
+
/** True if `pathname` targets the IDE forward prefix (`/ide` or `/ide/…`, never `/ideas`). */
|
|
9
|
+
export declare function matchIdePrefix(pathname: string): boolean;
|
|
10
|
+
//# sourceMappingURL=ide-prefix.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ide-prefix.d.ts","sourceRoot":"","sources":["../../../src/agent-farm/lib/ide-prefix.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,8EAA8E;AAC9E,eAAO,MAAM,kBAAkB,UAAU,CAAC;AAE1C,8FAA8F;AAC9F,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAGxD"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The IDE forward prefix (Issue #1668 §D1) and its matcher. Dependency-free on
|
|
3
|
+
* purpose: the auth seam (`utils/server-utils.ts`) imports it, and it must stay
|
|
4
|
+
* a light leaf (Issue #1869). `ide-record.ts` re-exports both.
|
|
5
|
+
*/
|
|
6
|
+
/** The fixed Tower prefix that routes to the IDE server (Issue #1668 §D1). */
|
|
7
|
+
export const IDE_DEFAULT_PREFIX = '/ide/';
|
|
8
|
+
/** True if `pathname` targets the IDE forward prefix (`/ide` or `/ide/…`, never `/ideas`). */
|
|
9
|
+
export function matchIdePrefix(pathname) {
|
|
10
|
+
const bare = IDE_DEFAULT_PREFIX.replace(/\/$/, ''); // "/ide"
|
|
11
|
+
return pathname === bare || pathname.startsWith(IDE_DEFAULT_PREFIX);
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=ide-prefix.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ide-prefix.js","sourceRoot":"","sources":["../../../src/agent-farm/lib/ide-prefix.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,8EAA8E;AAC9E,MAAM,CAAC,MAAM,kBAAkB,GAAG,OAAO,CAAC;AAE1C,8FAA8F;AAC9F,MAAM,UAAU,cAAc,CAAC,QAAgB;IAC7C,MAAM,IAAI,GAAG,kBAAkB,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS;IAC7D,OAAO,QAAQ,KAAK,IAAI,IAAI,QAAQ,CAAC,UAAU,CAAC,kBAAkB,CAAC,CAAC;AACtE,CAAC"}
|
|
@@ -12,8 +12,7 @@
|
|
|
12
12
|
* never hand-edited. Tower is the sole writer; `afx ide` drives it through the
|
|
13
13
|
* local `/api/ide` endpoint.
|
|
14
14
|
*/
|
|
15
|
-
|
|
16
|
-
export declare const IDE_DEFAULT_PREFIX = "/ide/";
|
|
15
|
+
export { IDE_DEFAULT_PREFIX, matchIdePrefix } from './ide-prefix.js';
|
|
17
16
|
/** Default port the local IDE server listens on when `--port` is not given. */
|
|
18
17
|
export declare const IDE_DEFAULT_PORT = 8200;
|
|
19
18
|
/**
|
|
@@ -27,8 +26,13 @@ export interface IdeServerRecord {
|
|
|
27
26
|
port: number;
|
|
28
27
|
serverPath: string;
|
|
29
28
|
pid: number;
|
|
30
|
-
defaultFolder?: string;
|
|
31
29
|
startedAt: string;
|
|
30
|
+
/** Base version the server reported at its spawn preflight (Spec 1789). Absent on a pre-#1789 record. */
|
|
31
|
+
serverVersion?: string;
|
|
32
|
+
/** The `--extensions-dir` the server was spawned with (Spec 1789). Absent on a pre-#1789 record. */
|
|
33
|
+
extensionsDir?: string;
|
|
34
|
+
/** Embedded sidebar version installed for the server (Spec 1789). Absent when none was embedded. */
|
|
35
|
+
sidebarVersion?: string;
|
|
32
36
|
}
|
|
33
37
|
/** Path to `~/.agent-farm/ide-server.json`. */
|
|
34
38
|
export declare function getIdeRecordPath(): string;
|
|
@@ -55,11 +59,24 @@ export declare function deleteIdeRecord(): void;
|
|
|
55
59
|
* Tower injects it at the forward instead.
|
|
56
60
|
*/
|
|
57
61
|
export declare function readIdeConnectionToken(): string | null;
|
|
62
|
+
/**
|
|
63
|
+
* Write a fresh connection token (randomBytes(32) hex, 0600), replacing any
|
|
64
|
+
* existing one, and return it (Issue #1869). Called before every IDE server
|
|
65
|
+
* SPAWN (never on adopt: a live server keeps the token it was started with), so
|
|
66
|
+
* a token that ever leaked into a browser jar is valid only for that server's
|
|
67
|
+
* uptime. Tower reads the token from this file on every forwarded request and
|
|
68
|
+
* overwrites any browser-held copy, so rotation breaks no client.
|
|
69
|
+
*/
|
|
70
|
+
export declare function rotateIdeConnectionToken(): string;
|
|
58
71
|
/**
|
|
59
72
|
* Return the Tower-owned connection token, generating and persisting one (0600)
|
|
60
73
|
* on first use. This token is the IDE server's own inner auth layer (passed via
|
|
61
74
|
* `--connection-token-file`); it is NOT a substitute for Tower's key check on
|
|
62
75
|
* the forward (Issue #1668 §D2).
|
|
76
|
+
*
|
|
77
|
+
* TEST SEAM: production code no longer calls this. Every spawn uses
|
|
78
|
+
* `rotateIdeConnectionToken` (Issue #1869), and the forward only reads the
|
|
79
|
+
* file. Tests use it to provision a token without forcing a new one.
|
|
63
80
|
*/
|
|
64
81
|
export declare function ensureIdeConnectionToken(): string;
|
|
65
82
|
//# sourceMappingURL=ide-record.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ide-record.d.ts","sourceRoot":"","sources":["../../../src/agent-farm/lib/ide-record.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;
|
|
1
|
+
{"version":3,"file":"ide-record.d.ts","sourceRoot":"","sources":["../../../src/agent-farm/lib/ide-record.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAiBH,OAAO,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAErE,+EAA+E;AAC/E,eAAO,MAAM,gBAAgB,OAAO,CAAC;AAKrC;;;;;GAKG;AACH,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;IAClB,yGAAyG;IACzG,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,oGAAoG;IACpG,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,oGAAoG;IACpG,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,+CAA+C;AAC/C,wBAAgB,gBAAgB,IAAI,MAAM,CAEzC;AAED,yDAAyD;AACzD,wBAAgB,yBAAyB,IAAI,MAAM,CAElD;AAED;;;;GAIG;AACH,wBAAgB,aAAa,IAAI,eAAe,GAAG,IAAI,CA2BtD;AAOD,wEAAwE;AACxE,wBAAgB,cAAc,CAAC,MAAM,EAAE,eAAe,GAAG,IAAI,CAQ5D;AAED,gEAAgE;AAChE,wBAAgB,eAAe,IAAI,IAAI,CAGtC;AAED;;;;;;;;;GASG;AACH,wBAAgB,sBAAsB,IAAI,MAAM,GAAG,IAAI,CAKtD;AAED;;;;;;;GAOG;AACH,wBAAgB,wBAAwB,IAAI,MAAM,CASjD;AAED;;;;;;;;;GASG;AACH,wBAAgB,wBAAwB,IAAI,MAAM,CAajD"}
|
|
@@ -16,8 +16,10 @@ import { readFileSync, writeFileSync, unlinkSync, existsSync, mkdirSync, chmodSy
|
|
|
16
16
|
import { randomBytes } from 'node:crypto';
|
|
17
17
|
import { resolve } from 'node:path';
|
|
18
18
|
import { AGENT_FARM_DIR } from './tower-client.js';
|
|
19
|
-
|
|
20
|
-
|
|
19
|
+
// The prefix and its matcher live in a dependency-free module so the auth seam
|
|
20
|
+
// (`utils/server-utils.ts`) can use them without importing this file's
|
|
21
|
+
// filesystem and tower-client dependencies (Issue #1869).
|
|
22
|
+
export { IDE_DEFAULT_PREFIX, matchIdePrefix } from './ide-prefix.js';
|
|
21
23
|
/** Default port the local IDE server listens on when `--port` is not given. */
|
|
22
24
|
export const IDE_DEFAULT_PORT = 8200;
|
|
23
25
|
const IDE_RECORD_FILENAME = 'ide-server.json';
|
|
@@ -53,14 +55,21 @@ export function readIdeRecord() {
|
|
|
53
55
|
port: parsed.port,
|
|
54
56
|
serverPath: parsed.serverPath,
|
|
55
57
|
pid: parsed.pid,
|
|
56
|
-
defaultFolder: typeof parsed.defaultFolder === 'string' ? parsed.defaultFolder : undefined,
|
|
57
58
|
startedAt: parsed.startedAt,
|
|
59
|
+
serverVersion: optionalString(parsed.serverVersion),
|
|
60
|
+
extensionsDir: optionalString(parsed.extensionsDir),
|
|
61
|
+
sidebarVersion: optionalString(parsed.sidebarVersion),
|
|
58
62
|
};
|
|
59
63
|
}
|
|
60
64
|
catch {
|
|
61
65
|
return null;
|
|
62
66
|
}
|
|
63
67
|
}
|
|
68
|
+
function optionalString(value) {
|
|
69
|
+
if (typeof value === 'string')
|
|
70
|
+
return value;
|
|
71
|
+
return undefined;
|
|
72
|
+
}
|
|
64
73
|
/** Write the IDE server record, creating `~/.agent-farm/` if needed. */
|
|
65
74
|
export function writeIdeRecord(record) {
|
|
66
75
|
if (!existsSync(AGENT_FARM_DIR)) {
|
|
@@ -94,11 +103,33 @@ export function readIdeConnectionToken() {
|
|
|
94
103
|
const token = readFileSync(path, 'utf-8').trim();
|
|
95
104
|
return token.length > 0 ? token : null;
|
|
96
105
|
}
|
|
106
|
+
/**
|
|
107
|
+
* Write a fresh connection token (randomBytes(32) hex, 0600), replacing any
|
|
108
|
+
* existing one, and return it (Issue #1869). Called before every IDE server
|
|
109
|
+
* SPAWN (never on adopt: a live server keeps the token it was started with), so
|
|
110
|
+
* a token that ever leaked into a browser jar is valid only for that server's
|
|
111
|
+
* uptime. Tower reads the token from this file on every forwarded request and
|
|
112
|
+
* overwrites any browser-held copy, so rotation breaks no client.
|
|
113
|
+
*/
|
|
114
|
+
export function rotateIdeConnectionToken() {
|
|
115
|
+
const path = getIdeConnectionTokenPath();
|
|
116
|
+
if (!existsSync(AGENT_FARM_DIR)) {
|
|
117
|
+
mkdirSync(AGENT_FARM_DIR, { recursive: true, mode: 0o700 });
|
|
118
|
+
}
|
|
119
|
+
const token = randomBytes(32).toString('hex');
|
|
120
|
+
writeFileSync(path, token + '\n', { mode: 0o600 });
|
|
121
|
+
chmodSync(path, 0o600);
|
|
122
|
+
return token;
|
|
123
|
+
}
|
|
97
124
|
/**
|
|
98
125
|
* Return the Tower-owned connection token, generating and persisting one (0600)
|
|
99
126
|
* on first use. This token is the IDE server's own inner auth layer (passed via
|
|
100
127
|
* `--connection-token-file`); it is NOT a substitute for Tower's key check on
|
|
101
128
|
* the forward (Issue #1668 §D2).
|
|
129
|
+
*
|
|
130
|
+
* TEST SEAM: production code no longer calls this. Every spawn uses
|
|
131
|
+
* `rotateIdeConnectionToken` (Issue #1869), and the forward only reads the
|
|
132
|
+
* file. Tests use it to provision a token without forcing a new one.
|
|
102
133
|
*/
|
|
103
134
|
export function ensureIdeConnectionToken() {
|
|
104
135
|
const path = getIdeConnectionTokenPath();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ide-record.js","sourceRoot":"","sources":["../../../src/agent-farm/lib/ide-record.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EACL,YAAY,EACZ,aAAa,EACb,UAAU,EACV,UAAU,EACV,SAAS,EACT,SAAS,GACV,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAEnD,
|
|
1
|
+
{"version":3,"file":"ide-record.js","sourceRoot":"","sources":["../../../src/agent-farm/lib/ide-record.ts"],"names":[],"mappings":"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"}
|