codebase-cli 2.0.0-pre.1 → 2.0.0-pre.10
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/dist/agent/agent.js +16 -1
- package/dist/agent/agent.js.map +1 -1
- package/dist/agent/config.js +71 -9
- package/dist/agent/config.js.map +1 -1
- package/dist/app-server/protocol.js +7 -0
- package/dist/app-server/protocol.js.map +1 -0
- package/dist/app-server/server.js +241 -0
- package/dist/app-server/server.js.map +1 -0
- package/dist/auth/flow.js +174 -41
- package/dist/auth/flow.js.map +1 -1
- package/dist/cli.js +60 -3
- package/dist/cli.js.map +1 -1
- package/dist/commands/builtins.js +272 -1
- package/dist/commands/builtins.js.map +1 -1
- package/dist/config/store.js +125 -0
- package/dist/config/store.js.map +1 -0
- package/dist/config/types.js +2 -0
- package/dist/config/types.js.map +1 -0
- package/dist/headless/run.js +129 -21
- package/dist/headless/run.js.map +1 -1
- package/dist/permissions/store.js +105 -3
- package/dist/permissions/store.js.map +1 -1
- package/dist/projects/cli.js +92 -0
- package/dist/projects/cli.js.map +1 -0
- package/dist/projects/client.js +120 -0
- package/dist/projects/client.js.map +1 -0
- package/dist/projects/types.js +2 -0
- package/dist/projects/types.js.map +1 -0
- package/dist/skills/platform-loader.js +133 -38
- package/dist/skills/platform-loader.js.map +1 -1
- package/dist/tools/config.js +74 -0
- package/dist/tools/config.js.map +1 -0
- package/dist/tools/dispatch-agent.js +16 -0
- package/dist/tools/dispatch-agent.js.map +1 -1
- package/dist/tools/registry.js +4 -0
- package/dist/tools/registry.js.map +1 -1
- package/dist/ui/App.js +1 -1
- package/dist/ui/App.js.map +1 -1
- package/dist/ui/FirstRunSetup.js +101 -15
- package/dist/ui/FirstRunSetup.js.map +1 -1
- package/dist/ui/Message.js +80 -1
- package/dist/ui/Message.js.map +1 -1
- package/dist/ui/Status.js +13 -2
- package/dist/ui/Status.js.map +1 -1
- package/package.json +3 -1
package/dist/headless/run.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run.js","sourceRoot":"","sources":["../../src/headless/run.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"run.js","sourceRoot":"","sources":["../../src/headless/run.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,80 @@
|
|
|
1
1
|
import { shellNeedsPermission } from "../tools/permission.js";
|
|
2
|
+
/**
|
|
3
|
+
* Convert a permission pattern's arg-glob portion into a regex.
|
|
4
|
+
* `*` → `.*`, `?` → `.`, everything else escaped. Anchored.
|
|
5
|
+
*/
|
|
6
|
+
function compileGlob(glob) {
|
|
7
|
+
const escaped = glob
|
|
8
|
+
.replace(/[.+^${}()|[\]\\]/g, "\\$&")
|
|
9
|
+
.replace(/\*/g, ".*")
|
|
10
|
+
.replace(/\?/g, ".");
|
|
11
|
+
return new RegExp(`^${escaped}$`);
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Pull the "primary string arg" from a tool-call args object. This
|
|
15
|
+
* is the value users typically want to glob against — the shell
|
|
16
|
+
* command, the file path, the URL, etc. Falls back to the JSON
|
|
17
|
+
* stringification so unknown tools still match in some way.
|
|
18
|
+
*/
|
|
19
|
+
function primaryArgString(toolName, args) {
|
|
20
|
+
const a = (args ?? {});
|
|
21
|
+
const pick = (k) => (typeof a[k] === "string" ? a[k] : "");
|
|
22
|
+
switch (toolName) {
|
|
23
|
+
case "shell":
|
|
24
|
+
return pick("command") || pick("cmd");
|
|
25
|
+
case "read_file":
|
|
26
|
+
case "write_file":
|
|
27
|
+
case "edit_file":
|
|
28
|
+
case "multi_edit":
|
|
29
|
+
case "notebook_edit":
|
|
30
|
+
return pick("path") || pick("file_path");
|
|
31
|
+
case "list_files":
|
|
32
|
+
return pick("path");
|
|
33
|
+
case "glob":
|
|
34
|
+
case "grep":
|
|
35
|
+
return pick("pattern");
|
|
36
|
+
case "web_fetch":
|
|
37
|
+
return pick("url");
|
|
38
|
+
case "web_search":
|
|
39
|
+
return pick("query");
|
|
40
|
+
default:
|
|
41
|
+
try {
|
|
42
|
+
return JSON.stringify(args);
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
return "";
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Compile a config-supplied list of `tool` or `tool:glob` patterns.
|
|
51
|
+
* Returns a matcher closure; the closure returns true when the tool
|
|
52
|
+
* call matches any pattern in the list.
|
|
53
|
+
*/
|
|
54
|
+
function compileMatcher(patterns) {
|
|
55
|
+
if (patterns.length === 0)
|
|
56
|
+
return () => false;
|
|
57
|
+
const compiled = patterns.map((pattern) => {
|
|
58
|
+
const colonIdx = pattern.indexOf(":");
|
|
59
|
+
if (colonIdx < 0) {
|
|
60
|
+
return { tool: pattern, regex: null };
|
|
61
|
+
}
|
|
62
|
+
const tool = pattern.slice(0, colonIdx);
|
|
63
|
+
const glob = pattern.slice(colonIdx + 1);
|
|
64
|
+
return { tool, regex: compileGlob(glob) };
|
|
65
|
+
});
|
|
66
|
+
return (toolName, args) => {
|
|
67
|
+
for (const { tool, regex } of compiled) {
|
|
68
|
+
if (tool !== toolName)
|
|
69
|
+
continue;
|
|
70
|
+
if (!regex)
|
|
71
|
+
return true;
|
|
72
|
+
if (regex.test(primaryArgString(toolName, args)))
|
|
73
|
+
return true;
|
|
74
|
+
}
|
|
75
|
+
return false;
|
|
76
|
+
};
|
|
77
|
+
}
|
|
2
78
|
/**
|
|
3
79
|
* Tools that never need a permission prompt. The full read-only set
|
|
4
80
|
* (audit-flagged "read-only allowlist" from permission.go) plus the task
|
|
@@ -26,14 +102,26 @@ const ALWAYS_ALLOWED = new Set([
|
|
|
26
102
|
// Memory tools are user-context, not destructive code edits — auto-allow.
|
|
27
103
|
"save_memory",
|
|
28
104
|
"read_memory",
|
|
105
|
+
// `config` is read-only.
|
|
106
|
+
"config",
|
|
29
107
|
]);
|
|
30
108
|
/**
|
|
31
109
|
* Per-agent-instance permission store. Used by the agent's
|
|
32
110
|
* beforeToolCall hook to decide whether to allow, prompt, or block.
|
|
33
111
|
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
112
|
+
* Decision order, highest priority first:
|
|
113
|
+
* 1. config-supplied deny patterns → block immediately
|
|
114
|
+
* 2. session-scoped "trust-all" response → allow
|
|
115
|
+
* 3. session-scoped "trust-tool" response → allow for that tool
|
|
116
|
+
* 4. built-in ALWAYS_ALLOWED read-only set → allow
|
|
117
|
+
* 5. config-supplied allow patterns → allow
|
|
118
|
+
* 6. shell-/git-branch-specific read heuristics → allow
|
|
119
|
+
* 7. otherwise → prompt the user
|
|
120
|
+
*
|
|
121
|
+
* Trust state from interactive responses is in-memory (session-only).
|
|
122
|
+
* Persisting it across sessions is what the config layer is for —
|
|
123
|
+
* users can promote a session-scoped trust to a config entry by
|
|
124
|
+
* editing ~/.codebase/config.json.
|
|
37
125
|
*/
|
|
38
126
|
export class PermissionStore {
|
|
39
127
|
trustAll = false;
|
|
@@ -41,9 +129,23 @@ export class PermissionStore {
|
|
|
41
129
|
queue = [];
|
|
42
130
|
listeners = new Set();
|
|
43
131
|
counter = 0;
|
|
132
|
+
matchAllow;
|
|
133
|
+
matchDeny;
|
|
134
|
+
autoApprove;
|
|
135
|
+
constructor(options = {}) {
|
|
136
|
+
this.matchAllow = compileMatcher(options.allowPatterns ?? []);
|
|
137
|
+
this.matchDeny = compileMatcher(options.denyPatterns ?? []);
|
|
138
|
+
this.autoApprove = options.autoApprove ?? false;
|
|
139
|
+
}
|
|
44
140
|
async evaluate(toolName, args) {
|
|
141
|
+
if (this.matchDeny(toolName, args))
|
|
142
|
+
return "block";
|
|
45
143
|
if (this.shouldAutoAllow(toolName, args))
|
|
46
144
|
return "allow";
|
|
145
|
+
if (this.matchAllow(toolName, args))
|
|
146
|
+
return "allow";
|
|
147
|
+
if (this.autoApprove)
|
|
148
|
+
return "allow";
|
|
47
149
|
return new Promise((resolve) => {
|
|
48
150
|
const request = {
|
|
49
151
|
id: `perm-${++this.counter}`,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/permissions/store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/permissions/store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { defaultDownloadPath, NotAuthenticatedError, ProjectClient, ProjectClientError } from "./client.js";
|
|
2
|
+
/**
|
|
3
|
+
* Dispatch a `codebase project …` subcommand. Returns the exit code
|
|
4
|
+
* to surface from the parent process.
|
|
5
|
+
*
|
|
6
|
+
* Recognized argv (relative to the entry point — argv[0] is the
|
|
7
|
+
* "project" word that the dispatcher already matched):
|
|
8
|
+
* project → list (default)
|
|
9
|
+
* project list → list
|
|
10
|
+
* project pull <id> → pull project to ~/.codebase/pulls/<id>.zip
|
|
11
|
+
* project pull <id> <dest> → pull to <dest>
|
|
12
|
+
*/
|
|
13
|
+
export async function runProjectSubcommand(argv, options = {}) {
|
|
14
|
+
const out = options.stdout ?? ((m) => process.stdout.write(`${m}\n`));
|
|
15
|
+
const err = options.stderr ?? ((m) => process.stderr.write(`${m}\n`));
|
|
16
|
+
const client = options.client ?? new ProjectClient();
|
|
17
|
+
const subcommand = argv[1] ?? "list";
|
|
18
|
+
try {
|
|
19
|
+
switch (subcommand) {
|
|
20
|
+
case "list":
|
|
21
|
+
case "ls":
|
|
22
|
+
return await listCmd(client, out);
|
|
23
|
+
case "pull":
|
|
24
|
+
return await pullCmd(client, argv[2], argv[3], out, err);
|
|
25
|
+
default:
|
|
26
|
+
err(`unknown subcommand: ${subcommand}`);
|
|
27
|
+
err("usage: codebase project [list | pull <id> [dest]]");
|
|
28
|
+
return 2;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
catch (e) {
|
|
32
|
+
if (e instanceof NotAuthenticatedError) {
|
|
33
|
+
err(e.message);
|
|
34
|
+
return 1;
|
|
35
|
+
}
|
|
36
|
+
if (e instanceof ProjectClientError) {
|
|
37
|
+
err(`error: ${e.message}`);
|
|
38
|
+
return e.status === 404 ? 4 : 1;
|
|
39
|
+
}
|
|
40
|
+
err(`error: ${e instanceof Error ? e.message : String(e)}`);
|
|
41
|
+
return 1;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
async function listCmd(client, out) {
|
|
45
|
+
const projects = await client.list();
|
|
46
|
+
if (projects.length === 0) {
|
|
47
|
+
out("(no projects yet — build one at https://codebase.design or pull an existing one)");
|
|
48
|
+
return 0;
|
|
49
|
+
}
|
|
50
|
+
out(`${projects.length} project${projects.length === 1 ? "" : "s"}:`);
|
|
51
|
+
out("");
|
|
52
|
+
for (const p of projects) {
|
|
53
|
+
out(formatProjectLine(p));
|
|
54
|
+
}
|
|
55
|
+
out("");
|
|
56
|
+
out("pull one with: codebase project pull <id>");
|
|
57
|
+
return 0;
|
|
58
|
+
}
|
|
59
|
+
async function pullCmd(client, projectId, dest, out, err) {
|
|
60
|
+
if (!projectId) {
|
|
61
|
+
err("usage: codebase project pull <id> [dest]");
|
|
62
|
+
return 2;
|
|
63
|
+
}
|
|
64
|
+
if (!client.hasCredentials()) {
|
|
65
|
+
throw new NotAuthenticatedError();
|
|
66
|
+
}
|
|
67
|
+
const target = dest ?? defaultDownloadPath(projectId);
|
|
68
|
+
out(`pulling ${projectId} → ${target}`);
|
|
69
|
+
const result = await client.pull(projectId, dest);
|
|
70
|
+
const kb = (result.bytes / 1024).toFixed(1);
|
|
71
|
+
out(`✓ wrote ${result.path} (${kb} KB)`);
|
|
72
|
+
out("");
|
|
73
|
+
out(`unzip with: unzip -d ./${projectId} ${result.path}`);
|
|
74
|
+
return 0;
|
|
75
|
+
}
|
|
76
|
+
function formatProjectLine(p) {
|
|
77
|
+
const id = p.id.padEnd(36);
|
|
78
|
+
const title = (p.title ?? "(untitled)").padEnd(28);
|
|
79
|
+
const sourceTag = p.source === "storage-only" ? " [storage]" : "";
|
|
80
|
+
const date = p.publishedAt
|
|
81
|
+
? ` · published ${shortDate(p.publishedAt)}`
|
|
82
|
+
: p.createdAt
|
|
83
|
+
? ` · created ${shortDate(p.createdAt)}`
|
|
84
|
+
: "";
|
|
85
|
+
return ` ${id} ${title}${sourceTag}${date}`;
|
|
86
|
+
}
|
|
87
|
+
function shortDate(iso) {
|
|
88
|
+
// Strip the time portion for the listing — full ISO is verbose
|
|
89
|
+
// and the user just wants to scan dates.
|
|
90
|
+
return iso.slice(0, 10);
|
|
91
|
+
}
|
|
92
|
+
//# sourceMappingURL=cli.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/projects/cli.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import { createWriteStream, mkdirSync, statSync } from "node:fs";
|
|
2
|
+
import { homedir } from "node:os";
|
|
3
|
+
import { dirname, join } from "node:path";
|
|
4
|
+
import { Readable } from "node:stream";
|
|
5
|
+
import { pipeline } from "node:stream/promises";
|
|
6
|
+
import { CredentialsStore } from "../auth/credentials.js";
|
|
7
|
+
const DEFAULT_BASE = "https://codebase.design";
|
|
8
|
+
export class NotAuthenticatedError extends Error {
|
|
9
|
+
constructor() {
|
|
10
|
+
super("not signed in to codebase.design. Run `codebase auth login`, or use BYOK by setting an *_API_KEY env var.");
|
|
11
|
+
this.name = "NotAuthenticatedError";
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
export class ProjectClientError extends Error {
|
|
15
|
+
status;
|
|
16
|
+
constructor(message, status) {
|
|
17
|
+
super(message);
|
|
18
|
+
this.status = status;
|
|
19
|
+
this.name = "ProjectClientError";
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Read-only client for the `/cli/projects` endpoints on
|
|
24
|
+
* codebase.design. Both endpoints require the `projects` scope on
|
|
25
|
+
* the access token — already requested by the OAuth flow's default
|
|
26
|
+
* scopes (`inference projects credits`).
|
|
27
|
+
*/
|
|
28
|
+
export class ProjectClient {
|
|
29
|
+
baseUrl;
|
|
30
|
+
credStore;
|
|
31
|
+
fetchFn;
|
|
32
|
+
constructor(opts = {}) {
|
|
33
|
+
this.baseUrl = (opts.baseUrl ?? DEFAULT_BASE).replace(/\/+$/, "");
|
|
34
|
+
this.credStore = opts.credentials ?? new CredentialsStore();
|
|
35
|
+
this.fetchFn = opts.fetchFn ?? globalThis.fetch.bind(globalThis);
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* List the user's projects. Merges the Convex-sourced list with
|
|
39
|
+
* raw storage-only entries the backend reports separately, so the
|
|
40
|
+
* CLI sees both indexed-and-published projects and any work-in-
|
|
41
|
+
* progress trees that haven't been published yet.
|
|
42
|
+
*/
|
|
43
|
+
async list() {
|
|
44
|
+
const token = this.requireToken();
|
|
45
|
+
const res = await this.fetchFn(`${this.baseUrl}/api/cli/projects`, {
|
|
46
|
+
headers: { Authorization: `Bearer ${token}` },
|
|
47
|
+
});
|
|
48
|
+
if (res.status === 401)
|
|
49
|
+
throw new NotAuthenticatedError();
|
|
50
|
+
if (!res.ok) {
|
|
51
|
+
throw new ProjectClientError(`list projects failed: ${res.status} ${await res.text().catch(() => "")}`.trim(), res.status);
|
|
52
|
+
}
|
|
53
|
+
const body = (await res.json());
|
|
54
|
+
const indexed = (body.projects ?? []).map((p) => ({
|
|
55
|
+
...p,
|
|
56
|
+
source: "convex",
|
|
57
|
+
}));
|
|
58
|
+
const indexedIds = new Set(indexed.map((p) => p.id));
|
|
59
|
+
const storageOnly = [];
|
|
60
|
+
for (const id of body.s3Projects ?? []) {
|
|
61
|
+
if (indexedIds.has(id))
|
|
62
|
+
continue;
|
|
63
|
+
storageOnly.push({ id, source: "storage-only" });
|
|
64
|
+
}
|
|
65
|
+
return [...indexed, ...storageOnly];
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Download a project as a ZIP and stream-write it to `destPath`
|
|
69
|
+
* (or `~/.codebase/pulls/<id>.zip` if not given). Returns the path
|
|
70
|
+
* the bytes were written to plus the file size on disk so the
|
|
71
|
+
* caller can surface it.
|
|
72
|
+
*/
|
|
73
|
+
async pull(projectId, destPath) {
|
|
74
|
+
const token = this.requireToken();
|
|
75
|
+
const res = await this.fetchFn(`${this.baseUrl}/api/cli/projects/${encodeURIComponent(projectId)}/pull`, {
|
|
76
|
+
headers: { Authorization: `Bearer ${token}` },
|
|
77
|
+
});
|
|
78
|
+
if (res.status === 401)
|
|
79
|
+
throw new NotAuthenticatedError();
|
|
80
|
+
if (res.status === 404) {
|
|
81
|
+
throw new ProjectClientError(`project not found: ${projectId}`, 404);
|
|
82
|
+
}
|
|
83
|
+
if (!res.ok) {
|
|
84
|
+
throw new ProjectClientError(`pull failed: ${res.status} ${await res.text().catch(() => "")}`.trim(), res.status);
|
|
85
|
+
}
|
|
86
|
+
const finalPath = destPath ?? defaultPullPath(projectId);
|
|
87
|
+
mkdirSync(dirname(finalPath), { recursive: true });
|
|
88
|
+
if (!res.body) {
|
|
89
|
+
throw new ProjectClientError("pull response had no body", res.status);
|
|
90
|
+
}
|
|
91
|
+
await pipeline(Readable.fromWeb(res.body), createWriteStream(finalPath));
|
|
92
|
+
const bytes = statSync(finalPath).size;
|
|
93
|
+
return { path: finalPath, bytes };
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Convenience: returns the loaded credential, or null if none.
|
|
97
|
+
* Useful for slash commands that want to gracefully degrade
|
|
98
|
+
* instead of throwing.
|
|
99
|
+
*/
|
|
100
|
+
hasCredentials() {
|
|
101
|
+
const creds = this.credStore.load();
|
|
102
|
+
return !!creds && !this.credStore.isExpired(creds);
|
|
103
|
+
}
|
|
104
|
+
requireToken() {
|
|
105
|
+
const creds = this.credStore.load();
|
|
106
|
+
if (!creds || this.credStore.isExpired(creds)) {
|
|
107
|
+
throw new NotAuthenticatedError();
|
|
108
|
+
}
|
|
109
|
+
return creds.accessToken;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
function defaultPullPath(projectId) {
|
|
113
|
+
const safe = projectId.replace(/[^a-zA-Z0-9._-]/g, "_");
|
|
114
|
+
return join(homedir(), ".codebase", "pulls", `${safe}.zip`);
|
|
115
|
+
}
|
|
116
|
+
/** Re-export so callers can pre-check the destination path. */
|
|
117
|
+
export function defaultDownloadPath(projectId) {
|
|
118
|
+
return defaultPullPath(projectId);
|
|
119
|
+
}
|
|
120
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/projects/client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/projects/types.ts"],"names":[],"mappings":""}
|
|
@@ -1,15 +1,20 @@
|
|
|
1
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { homedir } from "node:os";
|
|
3
|
+
import { dirname, join } from "node:path";
|
|
4
|
+
import { CredentialsStore } from "../auth/credentials.js";
|
|
5
|
+
const DEFAULT_BASE_URL = "https://codebase.design/api/cli";
|
|
6
|
+
const DEFAULT_CACHE_PATH = join(homedir(), ".codebase", "cache", "platform-assets.json");
|
|
7
|
+
const DEFAULT_TTL_MS = 60 * 60 * 1000; // 1 hour
|
|
1
8
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
9
|
+
* Fetches the user's curated skills/templates/prompts from
|
|
10
|
+
* codebase.design and merges them into the AssetRegistry. Caches
|
|
11
|
+
* the response under ~/.codebase/cache/platform-assets.json so
|
|
12
|
+
* subsequent CLI launches don't pay the round trip.
|
|
4
13
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* Phase 7+ implementation lands, it slots in here without further
|
|
8
|
-
* surgery to the agent or App layer.
|
|
14
|
+
* Wire format (server returns one bundle, the loader fans it out
|
|
15
|
+
* into the three asset kinds):
|
|
9
16
|
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
* GET https://codebase.foundation/api/cli/skills
|
|
17
|
+
* GET ${baseUrl}/assets
|
|
13
18
|
* Authorization: Bearer <accessToken>
|
|
14
19
|
*
|
|
15
20
|
* 200 OK
|
|
@@ -17,47 +22,137 @@
|
|
|
17
22
|
* "templates": [ { id, name, description, body, files?, tags? }, … ],
|
|
18
23
|
* "prompts": [ { id, name, description, body, tags? }, … ] }
|
|
19
24
|
*
|
|
20
|
-
*
|
|
21
|
-
* an ETag header so subsequent CLI launches don't pay the round trip.
|
|
22
|
-
* Refresh on `codebase auth refresh` or after 1 hour, whichever is
|
|
23
|
-
* sooner. Refresh failures fall back to the cached response — never
|
|
24
|
-
* leave a session stranded because the platform is briefly down.
|
|
25
|
+
* Behavior matrix:
|
|
25
26
|
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
27
|
+
* not signed in → returns [] without a network call
|
|
28
|
+
* network error → returns the last cached body if any,
|
|
29
|
+
* else [] (silent — never crashes a session)
|
|
30
|
+
* 404 (endpoint TBD) → caches an empty bundle, returns []
|
|
31
|
+
* (no warning — the backend half is
|
|
32
|
+
* expected to land later, see
|
|
33
|
+
* docs/plans/2026-05-09-codebase-cli-
|
|
34
|
+
* oauth-server-side.md §3-4)
|
|
35
|
+
* 200 → caches body + ETag, returns shaped list
|
|
36
|
+
* 304 (ETag match) → bumps the cache timestamp, returns cached
|
|
29
37
|
*/
|
|
30
38
|
export class PlatformLoader {
|
|
39
|
+
source = "platform";
|
|
31
40
|
credentials;
|
|
32
41
|
baseUrl;
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
42
|
+
cachePath;
|
|
43
|
+
ttlMs;
|
|
44
|
+
fetchFn;
|
|
45
|
+
now;
|
|
46
|
+
inFlight = null;
|
|
47
|
+
constructor(options = {}) {
|
|
48
|
+
this.credentials = options.credentials ?? new CredentialsStore();
|
|
49
|
+
this.baseUrl = (options.baseUrl ?? DEFAULT_BASE_URL).replace(/\/+$/, "");
|
|
50
|
+
this.cachePath = options.cachePath ?? DEFAULT_CACHE_PATH;
|
|
51
|
+
this.ttlMs = options.ttlMs ?? DEFAULT_TTL_MS;
|
|
52
|
+
this.fetchFn = options.fetchFn ?? globalThis.fetch.bind(globalThis);
|
|
53
|
+
this.now = options.now ?? Date.now;
|
|
37
54
|
}
|
|
38
55
|
async listSkills() {
|
|
39
|
-
|
|
40
|
-
return [];
|
|
56
|
+
const bundle = await this.bundle();
|
|
57
|
+
return (bundle.skills ?? []).map((s) => ({ ...s, kind: "skill", source: this.source }));
|
|
41
58
|
}
|
|
42
59
|
async listTemplates() {
|
|
43
|
-
|
|
60
|
+
const bundle = await this.bundle();
|
|
61
|
+
return (bundle.templates ?? []).map((t) => ({ ...t, kind: "template", source: this.source }));
|
|
44
62
|
}
|
|
45
63
|
async listPrompts() {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
64
|
+
const bundle = await this.bundle();
|
|
65
|
+
return (bundle.prompts ?? []).map((p) => ({ ...p, kind: "prompt", source: this.source }));
|
|
66
|
+
}
|
|
67
|
+
/** Force the next list call to re-fetch instead of using the cache. */
|
|
68
|
+
invalidate() {
|
|
69
|
+
try {
|
|
70
|
+
if (existsSync(this.cachePath)) {
|
|
71
|
+
writeFileSync(this.cachePath, JSON.stringify({ fetchedAt: 0, body: {} }));
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
catch {
|
|
75
|
+
// non-fatal
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
async bundle() {
|
|
79
|
+
// Coalesce concurrent calls — listSkills + listTemplates + listPrompts
|
|
80
|
+
// from a single registry pass should share one fetch.
|
|
81
|
+
if (this.inFlight)
|
|
82
|
+
return this.inFlight;
|
|
83
|
+
this.inFlight = this.bundleOnce().finally(() => {
|
|
84
|
+
this.inFlight = null;
|
|
85
|
+
});
|
|
86
|
+
return this.inFlight;
|
|
87
|
+
}
|
|
88
|
+
async bundleOnce() {
|
|
89
|
+
// Not signed in → never fetch, never cache, never warn.
|
|
90
|
+
const creds = this.credentials.load();
|
|
91
|
+
if (!creds || this.credentials.isExpired(creds))
|
|
92
|
+
return {};
|
|
93
|
+
const cached = readCache(this.cachePath);
|
|
94
|
+
const fresh = cached && this.now() - cached.fetchedAt < this.ttlMs;
|
|
95
|
+
if (fresh)
|
|
96
|
+
return cached.body;
|
|
97
|
+
try {
|
|
98
|
+
const headers = {
|
|
99
|
+
Authorization: `Bearer ${creds.accessToken}`,
|
|
100
|
+
Accept: "application/json",
|
|
101
|
+
};
|
|
102
|
+
if (cached?.etag)
|
|
103
|
+
headers["If-None-Match"] = cached.etag;
|
|
104
|
+
const res = await this.fetchFn(`${this.baseUrl}/assets`, { headers });
|
|
105
|
+
if (res.status === 304 && cached) {
|
|
106
|
+
// ETag match — bump the cache timestamp, return cached body.
|
|
107
|
+
writeCache(this.cachePath, { ...cached, fetchedAt: this.now() });
|
|
108
|
+
return cached.body;
|
|
109
|
+
}
|
|
110
|
+
if (res.status === 404) {
|
|
111
|
+
// Endpoint TBD. Cache an empty bundle so we don't hammer the
|
|
112
|
+
// server until the next TTL window.
|
|
113
|
+
const empty = { fetchedAt: this.now(), body: {} };
|
|
114
|
+
writeCache(this.cachePath, empty);
|
|
115
|
+
return empty.body;
|
|
116
|
+
}
|
|
117
|
+
if (res.status === 401 || !res.ok) {
|
|
118
|
+
// Auth blip or transient 5xx — fall back to whatever's cached.
|
|
119
|
+
return cached?.body ?? {};
|
|
120
|
+
}
|
|
121
|
+
const body = (await res.json());
|
|
122
|
+
const etag = res.headers.get("ETag") ?? undefined;
|
|
123
|
+
writeCache(this.cachePath, { fetchedAt: this.now(), etag, body });
|
|
124
|
+
return body;
|
|
125
|
+
}
|
|
126
|
+
catch {
|
|
127
|
+
// Network failures degrade to cached. Never throw — a flaky
|
|
128
|
+
// platform shouldn't take the agent down.
|
|
129
|
+
return cached?.body ?? {};
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
function readCache(path) {
|
|
134
|
+
if (!existsSync(path))
|
|
135
|
+
return null;
|
|
136
|
+
try {
|
|
137
|
+
const raw = readFileSync(path, "utf8");
|
|
138
|
+
const parsed = JSON.parse(raw);
|
|
139
|
+
if (typeof parsed.fetchedAt !== "number")
|
|
140
|
+
return null;
|
|
141
|
+
if (!parsed.body || typeof parsed.body !== "object")
|
|
142
|
+
return null;
|
|
143
|
+
return parsed;
|
|
144
|
+
}
|
|
145
|
+
catch {
|
|
60
146
|
return null;
|
|
61
147
|
}
|
|
62
148
|
}
|
|
149
|
+
function writeCache(path, bundle) {
|
|
150
|
+
try {
|
|
151
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
152
|
+
writeFileSync(path, JSON.stringify(bundle));
|
|
153
|
+
}
|
|
154
|
+
catch {
|
|
155
|
+
// non-fatal — the in-memory result still serves the current process
|
|
156
|
+
}
|
|
157
|
+
}
|
|
63
158
|
//# sourceMappingURL=platform-loader.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"platform-loader.js","sourceRoot":"","sources":["../../src/skills/platform-loader.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"platform-loader.js","sourceRoot":"","sources":["../../src/skills/platform-loader.ts"],"names":[],"mappings":"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"}
|