@cerebro-labs/agentnava-sdk 0.26.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. package/LICENSE +202 -0
  2. package/NOTICE +12 -0
  3. package/README.md +230 -0
  4. package/agent.d.ts +285 -0
  5. package/agent.js +394 -0
  6. package/agent.js.map +1 -0
  7. package/attach.d.ts +49 -0
  8. package/attach.js +115 -0
  9. package/attach.js.map +1 -0
  10. package/connection-status.d.ts +28 -0
  11. package/connection-status.js +61 -0
  12. package/connection-status.js.map +1 -0
  13. package/connection.d.ts +89 -0
  14. package/connection.js +143 -0
  15. package/connection.js.map +1 -0
  16. package/conversation.d.ts +177 -0
  17. package/conversation.js +348 -0
  18. package/conversation.js.map +1 -0
  19. package/end-user.d.ts +159 -0
  20. package/end-user.js +209 -0
  21. package/end-user.js.map +1 -0
  22. package/errors.d.ts +43 -0
  23. package/errors.js +55 -0
  24. package/errors.js.map +1 -0
  25. package/http.d.ts +32 -0
  26. package/http.js +192 -0
  27. package/http.js.map +1 -0
  28. package/import-tools.d.ts +282 -0
  29. package/import-tools.js +686 -0
  30. package/import-tools.js.map +1 -0
  31. package/index.d.ts +16 -0
  32. package/index.js +38 -0
  33. package/index.js.map +1 -0
  34. package/knowledge-base.d.ts +165 -0
  35. package/knowledge-base.js +274 -0
  36. package/knowledge-base.js.map +1 -0
  37. package/load-agent-dir.d.ts +17 -0
  38. package/load-agent-dir.js +192 -0
  39. package/load-agent-dir.js.map +1 -0
  40. package/package.json +32 -0
  41. package/project.d.ts +94 -0
  42. package/project.js +155 -0
  43. package/project.js.map +1 -0
  44. package/secret.d.ts +45 -0
  45. package/secret.js +69 -0
  46. package/secret.js.map +1 -0
  47. package/templates-inline.d.ts +2 -0
  48. package/templates-inline.js +16 -0
  49. package/templates-inline.js.map +1 -0
  50. package/templates.d.ts +16 -0
  51. package/templates.js +32 -0
  52. package/templates.js.map +1 -0
  53. package/turn.d.ts +11 -0
  54. package/turn.js +244 -0
  55. package/turn.js.map +1 -0
  56. package/types.d.ts +485 -0
  57. package/types.js +4 -0
  58. package/types.js.map +1 -0
  59. package/version.d.ts +1 -0
  60. package/version.js +5 -0
  61. package/version.js.map +1 -0
  62. package/workflows.d.ts +36 -0
  63. package/workflows.js +101 -0
  64. package/workflows.js.map +1 -0
  65. package/workspace.d.ts +290 -0
  66. package/workspace.js +390 -0
  67. package/workspace.js.map +1 -0
package/project.d.ts ADDED
@@ -0,0 +1,94 @@
1
+ import { Conversation } from './conversation.ts';
2
+ import type { Http } from './http.ts';
3
+ import type { FileEntry, ProjectData, ProjectFields } from './types.ts';
4
+ export interface ProjectStartOptions {
5
+ parameters?: Record<string, string | number>;
6
+ }
7
+ export interface FileUrlOptions {
8
+ download?: boolean;
9
+ ttl?: number;
10
+ }
11
+ /**
12
+ * A project you can work with. Holding one makes no request.
13
+ *
14
+ * The difference from an agent is the shared folder: every agent on a project
15
+ * reads and writes the SAME files, which is what lets one pick up where another
16
+ * left off. Two conversations with the same agent share nothing; two agents on
17
+ * the same project share everything in that folder.
18
+ */
19
+ export declare class Project {
20
+ #private;
21
+ readonly id: string;
22
+ private snapshot?;
23
+ constructor(http: Http, id: string, snapshot?: ProjectData);
24
+ private get base();
25
+ get data(): ProjectData | undefined;
26
+ get(): Promise<ProjectData>;
27
+ update(fields: ProjectFields): Promise<Project>;
28
+ addAgent(agentId: string): Promise<Project>;
29
+ removeAgent(agentId: string): Promise<Project>;
30
+ /** Stop it without destroying it. The folder and the history stay readable. */
31
+ archive(): Promise<Project>;
32
+ /** Delete it, and the shared folder with it. Archive is usually what you
33
+ * wanted. */
34
+ delete(): Promise<void>;
35
+ start(options?: ProjectStartOptions): Promise<Conversation>;
36
+ /**
37
+ * Address one of this project's conversations by id. No request.
38
+ *
39
+ * The sibling of `agent.conversation(id)`: the thing that owns it is the
40
+ * thing you ask.
41
+ *
42
+ * A PROJECT HAS ONE CONVERSATION PER AGENT, NOT ONE IN TOTAL. Starting a
43
+ * project opens the manager's conversation and one for every agent on the
44
+ * roster, so `conversations()` on a two-agent project returns three.
45
+ *
46
+ * This comment used to say a project had exactly one, which was true when it
47
+ * was written and had stopped being true by the time anyone read it.
48
+ * Observed on deployed staging on 2026-09-18: starting a project with Sal and
49
+ * Otis returned three, the manager's being the one with no `agent_id`.
50
+ *
51
+ * Tell them apart by `agent_id` on the wire row: absent means the manager,
52
+ * which is derived from the project rather than configured as an agent, and
53
+ * whose `conversation.agentId` reads `manager-<projectId>`.
54
+ *
55
+ * It resolves because `getSession` reads both session tables: an id does
56
+ * not say which one it came from, so the route answers for either.
57
+ */
58
+ conversation(conversationId: string): Conversation;
59
+ conversations(): Promise<Conversation[]>;
60
+ /** List one directory of the shared folder. Same `path` parameter as
61
+ * everywhere else on this API. */
62
+ files(path?: string): Promise<FileEntry[]>;
63
+ readFile(path: string): Promise<string>;
64
+ fileUrl(path: string, options?: FileUrlOptions): Promise<string>;
65
+ }
66
+ /** A project row as `/v1/projects` returns it: snake_case, nested. */
67
+ interface WireProject {
68
+ id: string;
69
+ workspace_id: string;
70
+ name: string;
71
+ status: string;
72
+ goal: string | null;
73
+ manager_instructions: string | null;
74
+ grade: string | null;
75
+ created_at: string;
76
+ updated_at: string;
77
+ }
78
+ interface WireMember {
79
+ project_id: string;
80
+ agent_id: string;
81
+ agent_version: number | null;
82
+ agent_name: string | null;
83
+ added_at: string;
84
+ }
85
+ /** The `{ project, agents }` envelope as one flat ProjectData.
86
+ *
87
+ * The envelope and the snake_case are what apps/console reads, so the wire
88
+ * stays and the SDK translates. A caller wants `project.agents`, not
89
+ * `response.agents` alongside `response.project`. */
90
+ export declare function toProjectData(body: {
91
+ project?: WireProject;
92
+ agents?: WireMember[];
93
+ } | WireProject): ProjectData;
94
+ export {};
package/project.js ADDED
@@ -0,0 +1,155 @@
1
+ // A project: several agents, one goal, one shared folder.
2
+ import { Conversation } from "./conversation.js";
3
+ /**
4
+ * A project you can work with. Holding one makes no request.
5
+ *
6
+ * The difference from an agent is the shared folder: every agent on a project
7
+ * reads and writes the SAME files, which is what lets one pick up where another
8
+ * left off. Two conversations with the same agent share nothing; two agents on
9
+ * the same project share everything in that folder.
10
+ */
11
+ export class Project {
12
+ id;
13
+ #http;
14
+ snapshot;
15
+ constructor(http, id, snapshot) {
16
+ this.#http = http;
17
+ this.id = id;
18
+ if (snapshot)
19
+ this.snapshot = snapshot;
20
+ }
21
+ get base() {
22
+ return `/v1/projects/${encodeURIComponent(this.id)}`;
23
+ }
24
+ get data() {
25
+ return this.snapshot;
26
+ }
27
+ async get() {
28
+ const data = toProjectData(await this.#http.get(this.base));
29
+ this.snapshot = data;
30
+ return data;
31
+ }
32
+ async update(fields) {
33
+ await this.#http.patch(this.base, fields);
34
+ // PATCH answers the row it wrote; re-read so the object carries the roster
35
+ // too, which the caller will ask for next.
36
+ return new Project(this.#http, this.id, await this.get());
37
+ }
38
+ async addAgent(agentId) {
39
+ const data = toProjectData(await this.#http.post(`${this.base}/agents`, { agentId }));
40
+ this.snapshot = data;
41
+ return new Project(this.#http, this.id, data);
42
+ }
43
+ async removeAgent(agentId) {
44
+ const data = toProjectData(await this.#http.delete(`${this.base}/agents/${encodeURIComponent(agentId)}`));
45
+ this.snapshot = data;
46
+ return new Project(this.#http, this.id, data);
47
+ }
48
+ /** Stop it without destroying it. The folder and the history stay readable. */
49
+ async archive() {
50
+ const data = toProjectData(await this.#http.post(`${this.base}/archive`));
51
+ this.snapshot = data;
52
+ return new Project(this.#http, this.id, data);
53
+ }
54
+ /** Delete it, and the shared folder with it. Archive is usually what you
55
+ * wanted. */
56
+ async delete() {
57
+ await this.#http.delete(this.base);
58
+ }
59
+ async start(options = {}) {
60
+ const data = await this.#http.post(`${this.base}/conversations`, {
61
+ ...(options.parameters && { parameters: options.parameters }),
62
+ });
63
+ // A project conversation and an agent conversation differ in what STARTED
64
+ // them, not in what you can do with one, so they share the class. The
65
+ // distinction that matters (which id it carries) is in the data.
66
+ return new Conversation(this.#http, data.id);
67
+ }
68
+ /**
69
+ * Address one of this project's conversations by id. No request.
70
+ *
71
+ * The sibling of `agent.conversation(id)`: the thing that owns it is the
72
+ * thing you ask.
73
+ *
74
+ * A PROJECT HAS ONE CONVERSATION PER AGENT, NOT ONE IN TOTAL. Starting a
75
+ * project opens the manager's conversation and one for every agent on the
76
+ * roster, so `conversations()` on a two-agent project returns three.
77
+ *
78
+ * This comment used to say a project had exactly one, which was true when it
79
+ * was written and had stopped being true by the time anyone read it.
80
+ * Observed on deployed staging on 2026-09-18: starting a project with Sal and
81
+ * Otis returned three, the manager's being the one with no `agent_id`.
82
+ *
83
+ * Tell them apart by `agent_id` on the wire row: absent means the manager,
84
+ * which is derived from the project rather than configured as an agent, and
85
+ * whose `conversation.agentId` reads `manager-<projectId>`.
86
+ *
87
+ * It resolves because `getSession` reads both session tables: an id does
88
+ * not say which one it came from, so the route answers for either.
89
+ */
90
+ conversation(conversationId) {
91
+ return new Conversation(this.#http, conversationId);
92
+ }
93
+ async conversations() {
94
+ // `sessions`, which is what the route actually answers with. This read
95
+ // `res.conversations`, which is always undefined, so `?? []` turned a SHAPE
96
+ // MISMATCH into a plausible empty list and every project reported having no
97
+ // conversations however many it had.
98
+ //
99
+ // The URL was never the problem: /conversations is a real alias for
100
+ // /sessions and both return `{ sessions: [...] }`. Only the key was wrong,
101
+ // which is why nothing 404'd and nothing looked broken.
102
+ //
103
+ // Same shape as the bugs this SDK's own end-to-end suite found on the
104
+ // server today: an absence read as an emptiness. `?? []` is the line that
105
+ // does the hiding, and it is load-bearing for a genuinely empty project, so
106
+ // the fix is to read the right key rather than to remove the fallback.
107
+ const res = await this.#http.get(`${this.base}/conversations`);
108
+ return (res.sessions ?? []).map((c) => new Conversation(this.#http, c.id));
109
+ }
110
+ // --------------------------------------------------------- the shared folder
111
+ /** List one directory of the shared folder. Same `path` parameter as
112
+ * everywhere else on this API. */
113
+ async files(path = '/') {
114
+ const res = await this.#http.get(`${this.base}/files`, { path });
115
+ return (res.files ?? []);
116
+ }
117
+ async readFile(path) {
118
+ // JSON `{path, content}`, not bare text. See Conversation.readFile.
119
+ const res = await this.#http.get(`${this.base}/files/content`, { path });
120
+ return res.content ?? '';
121
+ }
122
+ async fileUrl(path, options = {}) {
123
+ const res = await this.#http.post(`${this.base}/files/url`, {
124
+ path,
125
+ ...(options.download !== undefined && { download: options.download }),
126
+ ...(options.ttl !== undefined && { ttl: options.ttl }),
127
+ });
128
+ return res.url;
129
+ }
130
+ }
131
+ /** The `{ project, agents }` envelope as one flat ProjectData.
132
+ *
133
+ * The envelope and the snake_case are what apps/console reads, so the wire
134
+ * stays and the SDK translates. A caller wants `project.agents`, not
135
+ * `response.agents` alongside `response.project`. */
136
+ export function toProjectData(body) {
137
+ const p = ('project' in body ? body.project : body);
138
+ const members = ('agents' in body ? (body.agents ?? []) : []);
139
+ return {
140
+ id: p?.id ?? '',
141
+ name: p?.name ?? '',
142
+ goal: p?.goal ?? null,
143
+ managerInstructions: p?.manager_instructions ?? null,
144
+ grade: (p?.grade === 'premium' ? 'premium' : 'standard'),
145
+ status: p?.status === 'archived' ? 'archived' : 'active',
146
+ agents: members.map((m) => ({
147
+ agentId: m.agent_id,
148
+ name: m.agent_name ?? '',
149
+ addedAt: m.added_at,
150
+ })),
151
+ createdAt: p?.created_at ?? '',
152
+ updatedAt: p?.updated_at ?? '',
153
+ };
154
+ }
155
+ //# sourceMappingURL=project.js.map
package/project.js.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project.js","sourceRoot":"","sources":["../src/project.ts"],"names":[],"mappings":"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","sourcesContent":["// A project: several agents, one goal, one shared folder.\n\nimport { Conversation } from './conversation.ts';\nimport type { Http } from './http.ts';\nimport type { FileEntry, ProjectConversationData, ProjectData, ProjectFields } from './types.ts';\n\nexport interface ProjectStartOptions {\n\tparameters?: Record<string, string | number>;\n}\n\nexport interface FileUrlOptions {\n\tdownload?: boolean;\n\tttl?: number;\n}\n\n/**\n * A project you can work with. Holding one makes no request.\n *\n * The difference from an agent is the shared folder: every agent on a project\n * reads and writes the SAME files, which is what lets one pick up where another\n * left off. Two conversations with the same agent share nothing; two agents on\n * the same project share everything in that folder.\n */\nexport class Project {\n\treadonly id: string;\n\treadonly #http: Http;\n\tprivate snapshot?: ProjectData;\n\n\tconstructor(http: Http, id: string, snapshot?: ProjectData) {\n\t\tthis.#http = http;\n\t\tthis.id = id;\n\t\tif (snapshot) this.snapshot = snapshot;\n\t}\n\n\tprivate get base(): string {\n\t\treturn `/v1/projects/${encodeURIComponent(this.id)}`;\n\t}\n\n\tget data(): ProjectData | undefined {\n\t\treturn this.snapshot;\n\t}\n\n\tasync get(): Promise<ProjectData> {\n\t\tconst data = toProjectData(await this.#http.get(this.base));\n\t\tthis.snapshot = data;\n\t\treturn data;\n\t}\n\n\tasync update(fields: ProjectFields): Promise<Project> {\n\t\tawait this.#http.patch(this.base, fields);\n\t\t// PATCH answers the row it wrote; re-read so the object carries the roster\n\t\t// too, which the caller will ask for next.\n\t\treturn new Project(this.#http, this.id, await this.get());\n\t}\n\n\tasync addAgent(agentId: string): Promise<Project> {\n\t\tconst data = toProjectData(await this.#http.post(`${this.base}/agents`, { agentId }));\n\t\tthis.snapshot = data;\n\t\treturn new Project(this.#http, this.id, data);\n\t}\n\n\tasync removeAgent(agentId: string): Promise<Project> {\n\t\tconst data = toProjectData(\n\t\t\tawait this.#http.delete(`${this.base}/agents/${encodeURIComponent(agentId)}`),\n\t\t);\n\t\tthis.snapshot = data;\n\t\treturn new Project(this.#http, this.id, data);\n\t}\n\n\t/** Stop it without destroying it. The folder and the history stay readable. */\n\tasync archive(): Promise<Project> {\n\t\tconst data = toProjectData(await this.#http.post(`${this.base}/archive`));\n\t\tthis.snapshot = data;\n\t\treturn new Project(this.#http, this.id, data);\n\t}\n\n\t/** Delete it, and the shared folder with it. Archive is usually what you\n\t * wanted. */\n\tasync delete(): Promise<void> {\n\t\tawait this.#http.delete(this.base);\n\t}\n\n\tasync start(options: ProjectStartOptions = {}): Promise<Conversation> {\n\t\tconst data = await this.#http.post<ProjectConversationData>(`${this.base}/conversations`, {\n\t\t\t...(options.parameters && { parameters: options.parameters }),\n\t\t});\n\t\t// A project conversation and an agent conversation differ in what STARTED\n\t\t// them, not in what you can do with one, so they share the class. The\n\t\t// distinction that matters (which id it carries) is in the data.\n\t\treturn new Conversation(this.#http, data.id);\n\t}\n\n\t/**\n\t * Address one of this project's conversations by id. No request.\n\t *\n\t * The sibling of `agent.conversation(id)`: the thing that owns it is the\n\t * thing you ask.\n\t *\n\t * A PROJECT HAS ONE CONVERSATION PER AGENT, NOT ONE IN TOTAL. Starting a\n\t * project opens the manager's conversation and one for every agent on the\n\t * roster, so `conversations()` on a two-agent project returns three.\n\t *\n\t * This comment used to say a project had exactly one, which was true when it\n\t * was written and had stopped being true by the time anyone read it.\n\t * Observed on deployed staging on 2026-09-18: starting a project with Sal and\n\t * Otis returned three, the manager's being the one with no `agent_id`.\n\t *\n\t * Tell them apart by `agent_id` on the wire row: absent means the manager,\n\t * which is derived from the project rather than configured as an agent, and\n\t * whose `conversation.agentId` reads `manager-<projectId>`.\n\t *\n\t * It resolves because `getSession` reads both session tables: an id does\n\t * not say which one it came from, so the route answers for either.\n\t */\n\tconversation(conversationId: string): Conversation {\n\t\treturn new Conversation(this.#http, conversationId);\n\t}\n\n\tasync conversations(): Promise<Conversation[]> {\n\t\t// `sessions`, which is what the route actually answers with. This read\n\t\t// `res.conversations`, which is always undefined, so `?? []` turned a SHAPE\n\t\t// MISMATCH into a plausible empty list and every project reported having no\n\t\t// conversations however many it had.\n\t\t//\n\t\t// The URL was never the problem: /conversations is a real alias for\n\t\t// /sessions and both return `{ sessions: [...] }`. Only the key was wrong,\n\t\t// which is why nothing 404'd and nothing looked broken.\n\t\t//\n\t\t// Same shape as the bugs this SDK's own end-to-end suite found on the\n\t\t// server today: an absence read as an emptiness. `?? []` is the line that\n\t\t// does the hiding, and it is load-bearing for a genuinely empty project, so\n\t\t// the fix is to read the right key rather than to remove the fallback.\n\t\tconst res = await this.#http.get<{ sessions: ProjectConversationData[] }>(\n\t\t\t`${this.base}/conversations`,\n\t\t);\n\t\treturn (res.sessions ?? []).map((c) => new Conversation(this.#http, c.id));\n\t}\n\n\t// --------------------------------------------------------- the shared folder\n\n\t/** List one directory of the shared folder. Same `path` parameter as\n\t * everywhere else on this API. */\n\tasync files(path = '/'): Promise<FileEntry[]> {\n\t\tconst res = await this.#http.get<{ files: unknown[] }>(`${this.base}/files`, { path });\n\t\treturn (res.files ?? []) as FileEntry[];\n\t}\n\n\tasync readFile(path: string): Promise<string> {\n\t\t// JSON `{path, content}`, not bare text. See Conversation.readFile.\n\t\tconst res = await this.#http.get<{ path: string; content: string }>(\n\t\t\t`${this.base}/files/content`,\n\t\t\t{ path },\n\t\t);\n\t\treturn res.content ?? '';\n\t}\n\n\tasync fileUrl(path: string, options: FileUrlOptions = {}): Promise<string> {\n\t\tconst res = await this.#http.post<{ url: string }>(`${this.base}/files/url`, {\n\t\t\tpath,\n\t\t\t...(options.download !== undefined && { download: options.download }),\n\t\t\t...(options.ttl !== undefined && { ttl: options.ttl }),\n\t\t});\n\t\treturn res.url;\n\t}\n}\n\n/** A project row as `/v1/projects` returns it: snake_case, nested. */\ninterface WireProject {\n\tid: string;\n\tworkspace_id: string;\n\tname: string;\n\tstatus: string;\n\tgoal: string | null;\n\tmanager_instructions: string | null;\n\tgrade: string | null;\n\tcreated_at: string;\n\tupdated_at: string;\n}\n\ninterface WireMember {\n\tproject_id: string;\n\tagent_id: string;\n\tagent_version: number | null;\n\tagent_name: string | null;\n\tadded_at: string;\n}\n\n/** The `{ project, agents }` envelope as one flat ProjectData.\n *\n * The envelope and the snake_case are what apps/console reads, so the wire\n * stays and the SDK translates. A caller wants `project.agents`, not\n * `response.agents` alongside `response.project`. */\nexport function toProjectData(\n\tbody: { project?: WireProject; agents?: WireMember[] } | WireProject,\n): ProjectData {\n\tconst p = ('project' in body ? body.project : body) as WireProject;\n\tconst members = ('agents' in body ? (body.agents ?? []) : []) as WireMember[];\n\treturn {\n\t\tid: p?.id ?? '',\n\t\tname: p?.name ?? '',\n\t\tgoal: p?.goal ?? null,\n\t\tmanagerInstructions: p?.manager_instructions ?? null,\n\t\tgrade: (p?.grade === 'premium' ? 'premium' : 'standard'),\n\t\tstatus: p?.status === 'archived' ? 'archived' : 'active',\n\t\tagents: members.map((m) => ({\n\t\t\tagentId: m.agent_id,\n\t\t\tname: m.agent_name ?? '',\n\t\t\taddedAt: m.added_at,\n\t\t})),\n\t\tcreatedAt: p?.created_at ?? '',\n\t\tupdatedAt: p?.updated_at ?? '',\n\t};\n}\n"]}
package/secret.d.ts ADDED
@@ -0,0 +1,45 @@
1
+ import type { Http } from './http.ts';
2
+ import type { SecretMeta } from './types.ts';
3
+ /**
4
+ * A stored value you hold and act on.
5
+ *
6
+ * A CLASS, for the same reason `Connection` is: everything else in this SDK is
7
+ * a thing you hold, and a secret was the odd one out, a bare record with an id
8
+ * you carried around as a string.
9
+ *
10
+ * ```ts
11
+ * const key = await ws.secrets.create({ name: 'APOLLO_API_KEY', value, endUserId });
12
+ * await key.update('rotated-value');
13
+ * await key.delete();
14
+ * ```
15
+ *
16
+ * NOTHING READS THE VALUE BACK, including you. There is no `value` here and no
17
+ * method that returns one. That is deliberate rather than an omission: a value
18
+ * you can read is a value that ends up in a log. The agent substitutes it on
19
+ * the server at the moment a call goes out.
20
+ */
21
+ export declare class Secret {
22
+ #private;
23
+ readonly id: string;
24
+ private snapshot?;
25
+ constructor(http: Http, id: string, snapshot?: SecretMeta);
26
+ /** The name an agent references it by, as `{{secrets.NAME}}`. */
27
+ get name(): string | undefined;
28
+ /** The agent this is scoped to, or null when the whole workspace reads it. */
29
+ get agentId(): string | null | undefined;
30
+ /** The last-known record. Values are never part of it. */
31
+ get data(): SecretMeta | undefined;
32
+ /** The end user this belongs to, or null when it is the workspace's. */
33
+ get endUserId(): string | null | undefined;
34
+ /** Read it back: name, scope, owner, timestamps. Never the value.
35
+ *
36
+ * `ws.secret(id)` builds a handle that knows only its id, and until this
37
+ * existed there was no way for it to learn anything else. Attaching a secret
38
+ * needs its NAME, so a handle that could not answer that could not be
39
+ * attached. */
40
+ get(): Promise<SecretMeta>;
41
+ /** Replace the value. The name and scope do not move: rotating a key must
42
+ * not silently become a different secret. */
43
+ update(value: string, description?: string): Promise<Secret>;
44
+ delete(): Promise<void>;
45
+ }
package/secret.js ADDED
@@ -0,0 +1,69 @@
1
+ // A secret: a value your agents use and never see.
2
+ /**
3
+ * A stored value you hold and act on.
4
+ *
5
+ * A CLASS, for the same reason `Connection` is: everything else in this SDK is
6
+ * a thing you hold, and a secret was the odd one out, a bare record with an id
7
+ * you carried around as a string.
8
+ *
9
+ * ```ts
10
+ * const key = await ws.secrets.create({ name: 'APOLLO_API_KEY', value, endUserId });
11
+ * await key.update('rotated-value');
12
+ * await key.delete();
13
+ * ```
14
+ *
15
+ * NOTHING READS THE VALUE BACK, including you. There is no `value` here and no
16
+ * method that returns one. That is deliberate rather than an omission: a value
17
+ * you can read is a value that ends up in a log. The agent substitutes it on
18
+ * the server at the moment a call goes out.
19
+ */
20
+ export class Secret {
21
+ id;
22
+ #http;
23
+ snapshot;
24
+ constructor(http, id, snapshot) {
25
+ this.#http = http;
26
+ this.id = id;
27
+ if (snapshot)
28
+ this.snapshot = snapshot;
29
+ }
30
+ /** The name an agent references it by, as `{{secrets.NAME}}`. */
31
+ get name() {
32
+ return this.snapshot?.name;
33
+ }
34
+ /** The agent this is scoped to, or null when the whole workspace reads it. */
35
+ get agentId() {
36
+ return this.snapshot?.agentId;
37
+ }
38
+ /** The last-known record. Values are never part of it. */
39
+ get data() {
40
+ return this.snapshot;
41
+ }
42
+ /** The end user this belongs to, or null when it is the workspace's. */
43
+ get endUserId() {
44
+ return this.snapshot?.endUserId;
45
+ }
46
+ /** Read it back: name, scope, owner, timestamps. Never the value.
47
+ *
48
+ * `ws.secret(id)` builds a handle that knows only its id, and until this
49
+ * existed there was no way for it to learn anything else. Attaching a secret
50
+ * needs its NAME, so a handle that could not answer that could not be
51
+ * attached. */
52
+ async get() {
53
+ const res = await this.#http.get(`/v1/secrets/${encodeURIComponent(this.id)}`);
54
+ const meta = res.secret ?? res;
55
+ this.snapshot = meta;
56
+ return meta;
57
+ }
58
+ /** Replace the value. The name and scope do not move: rotating a key must
59
+ * not silently become a different secret. */
60
+ async update(value, description) {
61
+ const res = await this.#http.patch(`/v1/secrets/${encodeURIComponent(this.id)}`, { value, ...(description !== undefined && { description }) });
62
+ this.snapshot = res.secret ?? res;
63
+ return this;
64
+ }
65
+ async delete() {
66
+ await this.#http.delete(`/v1/secrets/${encodeURIComponent(this.id)}`);
67
+ }
68
+ }
69
+ //# sourceMappingURL=secret.js.map
package/secret.js.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"file":"secret.js","sourceRoot":"","sources":["../src/secret.ts"],"names":[],"mappings":"AAAA,mDAAmD;AAKnD;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,OAAO,MAAM;IACT,EAAE,CAAS;IACX,KAAK,CAAO;IACb,QAAQ,CAAc;IAE9B,YAAY,IAAU,EAAE,EAAU,EAAE,QAAqB;QACxD,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;QAClB,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC;QACb,IAAI,QAAQ;YAAE,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;IACxC,CAAC;IAED,iEAAiE;IACjE,IAAI,IAAI;QACP,OAAO,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC;IAC5B,CAAC;IAED,8EAA8E;IAC9E,IAAI,OAAO;QACV,OAAO,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC/B,CAAC;IAED,0DAA0D;IAC1D,IAAI,IAAI;QACP,OAAO,IAAI,CAAC,QAAQ,CAAC;IACtB,CAAC;IAED,wEAAwE;IACxE,IAAI,SAAS;QACZ,OAAO,IAAI,CAAC,QAAQ,EAAE,SAAS,CAAC;IACjC,CAAC;IAED;;;;;oBAKgB;IAChB,KAAK,CAAC,GAAG;QACR,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,GAAG,CAC/B,eAAe,kBAAkB,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAC5C,CAAC;QACF,MAAM,IAAI,GAAG,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC;QAC/B,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;QACrB,OAAO,IAAI,CAAC;IACb,CAAC;IAED;kDAC8C;IAC9C,KAAK,CAAC,MAAM,CAAC,KAAa,EAAE,WAAoB;QAC/C,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,KAAK,CACjC,eAAe,kBAAkB,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAC5C,EAAE,KAAK,EAAE,GAAG,CAAC,WAAW,KAAK,SAAS,IAAI,EAAE,WAAW,EAAE,CAAC,EAAE,CAC5D,CAAC;QACF,IAAI,CAAC,QAAQ,GAAG,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC;QAClC,OAAO,IAAI,CAAC;IACb,CAAC;IAED,KAAK,CAAC,MAAM;QACX,MAAM,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,eAAe,kBAAkB,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;IACvE,CAAC;CACD","sourcesContent":["// A secret: a value your agents use and never see.\n\nimport type { Http } from './http.ts';\nimport type { SecretMeta } from './types.ts';\n\n/**\n * A stored value you hold and act on.\n *\n * A CLASS, for the same reason `Connection` is: everything else in this SDK is\n * a thing you hold, and a secret was the odd one out, a bare record with an id\n * you carried around as a string.\n *\n * ```ts\n * const key = await ws.secrets.create({ name: 'APOLLO_API_KEY', value, endUserId });\n * await key.update('rotated-value');\n * await key.delete();\n * ```\n *\n * NOTHING READS THE VALUE BACK, including you. There is no `value` here and no\n * method that returns one. That is deliberate rather than an omission: a value\n * you can read is a value that ends up in a log. The agent substitutes it on\n * the server at the moment a call goes out.\n */\nexport class Secret {\n\treadonly id: string;\n\treadonly #http: Http;\n\tprivate snapshot?: SecretMeta;\n\n\tconstructor(http: Http, id: string, snapshot?: SecretMeta) {\n\t\tthis.#http = http;\n\t\tthis.id = id;\n\t\tif (snapshot) this.snapshot = snapshot;\n\t}\n\n\t/** The name an agent references it by, as `{{secrets.NAME}}`. */\n\tget name(): string | undefined {\n\t\treturn this.snapshot?.name;\n\t}\n\n\t/** The agent this is scoped to, or null when the whole workspace reads it. */\n\tget agentId(): string | null | undefined {\n\t\treturn this.snapshot?.agentId;\n\t}\n\n\t/** The last-known record. Values are never part of it. */\n\tget data(): SecretMeta | undefined {\n\t\treturn this.snapshot;\n\t}\n\n\t/** The end user this belongs to, or null when it is the workspace's. */\n\tget endUserId(): string | null | undefined {\n\t\treturn this.snapshot?.endUserId;\n\t}\n\n\t/** Read it back: name, scope, owner, timestamps. Never the value.\n\t *\n\t * `ws.secret(id)` builds a handle that knows only its id, and until this\n\t * existed there was no way for it to learn anything else. Attaching a secret\n\t * needs its NAME, so a handle that could not answer that could not be\n\t * attached. */\n\tasync get(): Promise<SecretMeta> {\n\t\tconst res = await this.#http.get<{ secret?: SecretMeta } & SecretMeta>(\n\t\t\t`/v1/secrets/${encodeURIComponent(this.id)}`,\n\t\t);\n\t\tconst meta = res.secret ?? res;\n\t\tthis.snapshot = meta;\n\t\treturn meta;\n\t}\n\n\t/** Replace the value. The name and scope do not move: rotating a key must\n\t * not silently become a different secret. */\n\tasync update(value: string, description?: string): Promise<Secret> {\n\t\tconst res = await this.#http.patch<{ secret?: SecretMeta } & SecretMeta>(\n\t\t\t`/v1/secrets/${encodeURIComponent(this.id)}`,\n\t\t\t{ value, ...(description !== undefined && { description }) },\n\t\t);\n\t\tthis.snapshot = res.secret ?? res;\n\t\treturn this;\n\t}\n\n\tasync delete(): Promise<void> {\n\t\tawait this.#http.delete(`/v1/secrets/${encodeURIComponent(this.id)}`);\n\t}\n}\n"]}
@@ -0,0 +1,2 @@
1
+ export declare const managerInstructions: string;
2
+ export declare const managerSpecJson: string;
@@ -0,0 +1,16 @@
1
+ // Auto-generated from packages/agentnava-sdk/templates/. Re-run
2
+ // `bun run scripts/regen-templates.mjs` after editing any template file.
3
+ // Inlined as base64 so the SDK ships TS source only. Consumers don't
4
+ // need to resolve filesystem paths at runtime.
5
+ function decode(b64) {
6
+ const bin = atob(b64);
7
+ const out = new Uint8Array(bin.length);
8
+ for (let i = 0; i < bin.length; i++)
9
+ out[i] = bin.charCodeAt(i);
10
+ return new TextDecoder().decode(out);
11
+ }
12
+ const MANAGER_MD_B64 = 'IyBNYW5hZ2VyCgpZb3UgYXJlIHRoZSAqKk1hbmFnZXIqKiBmb3IgeW91ciB0ZWFtLCB0aGUgcG9pbnQgb2YgY29udGFjdCBmb3IgdGhlCnVzZXIsIGFuZCB0aGUgb25lIHdobyBkZWNpZGVzIGhvdyBlYWNoIHJlcXVlc3QgZ2V0cyBoYW5kbGVkLgoKIyMgWW91ciByb2xlCgotICoqTGlzdGVuIGZpcnN0LioqIFVuZGVyc3RhbmQgd2hhdCB0aGUgdXNlciBhY3R1YWxseSB3YW50cyBiZWZvcmUKICByb3V0aW5nLiBBc2sgb25lIGZvY3VzZWQgY2xhcmlmeWluZyBxdWVzdGlvbiBpZiB0aGUgcmVxdWVzdCBpcwogIGFtYmlndW91czogZG9uJ3QgcGlsZSB1cCBjaGVja2xpc3RzLgotICoqRGVjaWRlOiBoYW5kbGUgZGlyZWN0bHksIG9yIGRlbGVnYXRlLioqIExpZ2h0IHF1ZXN0aW9ucywgc3VtbWFyaWVzLAogIHN0YXR1cyByZXBvcnRzLCBhbnl0aGluZyB0aGF0J3MgcHVyZSByZWNhbGwgb3Igc2ltcGxlIHJlYXNvbmluZywKICBhbnN3ZXIgeW91cnNlbGYuIEFueXRoaW5nIHRoYXQgbmVlZHMgYSBUZWFtbWF0ZSdzIHNwZWNpZmljCiAgY29tcGV0ZW5jZTogZGVsZWdhdGUgdG8gdGhhdCBUZWFtbWF0ZSBieSBuYW1lLgotICoqT25lIFRlYW1tYXRlIHBlciBkZWxlZ2F0aW9uLioqIERvbid0IGZhbiBvdXQgdG8gdGhyZWUgVGVhbW1hdGVzCiAgaG9waW5nIGZvciB0aGUgYmVzdCByZXNwb25zZS4gUGljayB0aGUgb25lIHdob3NlIHNraWxscyBtYXRjaCB0aGUKICByZXF1ZXN0IGFuZCBnaXZlIHRoZW0gYSBjbGVhciBicmllZi4KLSAqKlN5bnRoZXNpemUuKiogV2hlbiB0aGUgVGVhbW1hdGUgcmVwbGllcywgZm9sZCB0aGVpciBhbnN3ZXIgaW50bwogIG9uZSBjb2hlcmVudCByZXNwb25zZSB0byB0aGUgdXNlci4gVGhlIHVzZXIgc2hvdWxkbid0IGhhdmUgdG8KICBjb250ZXh0LXN3aXRjaCBiZXR3ZWVuIGFnZW50IHZvaWNlcy4KCiMjIEhvdyB0byBkZWxlZ2F0ZQoKVXNlIHRoZSBgRGVsZWdhdGVgIHRvb2wuIFRoZSBzaGFwZSBpczoKCmBgYApEZWxlZ2F0ZSh7CiAgdG86ICI8dGVhbW1hdGUta2V5PiIsICAgICAgICAgIC8vIHRoZWlyIGFnZW50IGtleSBpbiB0aGlzIHdvcmtzcGFjZQogIHByb21wdDogIjx0aGUgYWN0dWFsIGFzaz4iLCAgICAvLyB3aGF0IHlvdSB3YW50IHRoZW0gdG8gZG8KICBjb250ZXh0OiAiPG9wdGlvbmFsIHByZWFtYmxlPiIgLy8gd2hhdCB5b3UndmUgYWxyZWFkeSBsZWFybmVkIChpZiBhbnl0aGluZykKfSkKYGBgCgpUaGUgVGVhbW1hdGUgcnVucyBpbiBpdHMgb3duIGVwaGVtZXJhbCBzZXNzaW9uIGFuZCByZXR1cm5zIGl0cyBmaW5hbApyZXBseS4gWW91IHNlZSB0aGF0IHJlcGx5IGFzIHRoZSB0b29sIHJlc3VsdC4gU2VsZi1kZWxlZ2F0aW9uIGlzCnJlamVjdGVkLiBEZWxlZ2F0aW9uIGNoYWlucyBhcmUgY2FwcGVkIGF0IGRlcHRoIDMgKHlvdSDihpIgdGVhbW1hdGUg4oaSCnRoZWlyIGRlbGVnYXRpb247IG5vIGRlZXBlcikuCgojIyBSZXBvcnRpbmcKCldoZW4geW91IGFuc3dlciB0aGUgdXNlcjoKCi0gTGVhZCB3aXRoIHRoZSBhbnN3ZXIsIG5vdCB0aGUgcHJvY2Vzcy4KLSBEb24ndCBuYXJyYXRlIHdoaWNoIFRlYW1tYXRlIHlvdSBhc2tlZCB1bmxlc3MgdGhlIHVzZXIgZXhwbGljaXRseQogIGFza2VkIHdobyBkaWQgdGhlIHdvcmsuCi0gSWYgYSBkZWxlZ2F0aW9uIGZhaWxlZCwgdGVsbCB0aGUgdXNlciBwbGFpbmx5IHRoYXQgdGhlIGFuc3dlciBpc24ndAogIGF2YWlsYWJsZSBhbmQgKGJyaWVmbHkpIHdoeTogZG9uJ3QgZmFicmljYXRlLgo=';
13
+ const MANAGER_JSON_B64 = 'ewogICJrZXkiOiAibWFuYWdlciIsCiAgInJvbGUiOiAibWFuYWdlciIsCiAgIndlYlNlYXJjaCI6IGZhbHNlLAogICJfY29tbWVudCI6ICJJbnN0cnVjdGlvbnMgbGl2ZSBpbiBtYW5hZ2VyLm1kIChsb2FkZWQgYnkgc3JjL3RlbXBsYXRlcy50cykuIERlbGVnYXRlIGlzIGF1dG8tcmVnaXN0ZXJlZCBmb3IgYW55IHNwZWMgd2l0aCByb2xlPSdtYW5hZ2VyJyBieSB0aGUgd29ya2VycyBiYWNrZW5kOyBkZWNsYXJpbmcgaXQgaGVyZSBpcyBub3QgcmVxdWlyZWQuIgp9Cg==';
14
+ export const managerInstructions = decode(MANAGER_MD_B64);
15
+ export const managerSpecJson = decode(MANAGER_JSON_B64);
16
+ //# sourceMappingURL=templates-inline.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"templates-inline.js","sourceRoot":"","sources":["../src/templates-inline.ts"],"names":[],"mappings":"AAAA,gEAAgE;AAChE,yEAAyE;AACzE,qEAAqE;AACrE,+CAA+C;AAE/C,SAAS,MAAM,CAAC,GAAW;IAC1B,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC;IACtB,MAAM,GAAG,GAAG,IAAI,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IACvC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,EAAE;QAAE,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;IAChE,OAAO,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;AACtC,CAAC;AAED,MAAM,cAAc,GAAG,0xEAA0xE,CAAC;AAClzE,MAAM,gBAAgB,GAAG,sWAAsW,CAAC;AAEhY,MAAM,CAAC,MAAM,mBAAmB,GAAG,MAAM,CAAC,cAAc,CAAC,CAAC;AAC1D,MAAM,CAAC,MAAM,eAAe,GAAG,MAAM,CAAC,gBAAgB,CAAC,CAAC","sourcesContent":["// Auto-generated from packages/agentnava-sdk/templates/. Re-run\n// `bun run scripts/regen-templates.mjs` after editing any template file.\n// Inlined as base64 so the SDK ships TS source only. Consumers don't\n// need to resolve filesystem paths at runtime.\n\nfunction decode(b64: string): string {\n\tconst bin = atob(b64);\n\tconst out = new Uint8Array(bin.length);\n\tfor (let i = 0; i < bin.length; i++) out[i] = bin.charCodeAt(i);\n\treturn new TextDecoder().decode(out);\n}\n\nconst MANAGER_MD_B64 = 'IyBNYW5hZ2VyCgpZb3UgYXJlIHRoZSAqKk1hbmFnZXIqKiBmb3IgeW91ciB0ZWFtLCB0aGUgcG9pbnQgb2YgY29udGFjdCBmb3IgdGhlCnVzZXIsIGFuZCB0aGUgb25lIHdobyBkZWNpZGVzIGhvdyBlYWNoIHJlcXVlc3QgZ2V0cyBoYW5kbGVkLgoKIyMgWW91ciByb2xlCgotICoqTGlzdGVuIGZpcnN0LioqIFVuZGVyc3RhbmQgd2hhdCB0aGUgdXNlciBhY3R1YWxseSB3YW50cyBiZWZvcmUKICByb3V0aW5nLiBBc2sgb25lIGZvY3VzZWQgY2xhcmlmeWluZyBxdWVzdGlvbiBpZiB0aGUgcmVxdWVzdCBpcwogIGFtYmlndW91czogZG9uJ3QgcGlsZSB1cCBjaGVja2xpc3RzLgotICoqRGVjaWRlOiBoYW5kbGUgZGlyZWN0bHksIG9yIGRlbGVnYXRlLioqIExpZ2h0IHF1ZXN0aW9ucywgc3VtbWFyaWVzLAogIHN0YXR1cyByZXBvcnRzLCBhbnl0aGluZyB0aGF0J3MgcHVyZSByZWNhbGwgb3Igc2ltcGxlIHJlYXNvbmluZywKICBhbnN3ZXIgeW91cnNlbGYuIEFueXRoaW5nIHRoYXQgbmVlZHMgYSBUZWFtbWF0ZSdzIHNwZWNpZmljCiAgY29tcGV0ZW5jZTogZGVsZWdhdGUgdG8gdGhhdCBUZWFtbWF0ZSBieSBuYW1lLgotICoqT25lIFRlYW1tYXRlIHBlciBkZWxlZ2F0aW9uLioqIERvbid0IGZhbiBvdXQgdG8gdGhyZWUgVGVhbW1hdGVzCiAgaG9waW5nIGZvciB0aGUgYmVzdCByZXNwb25zZS4gUGljayB0aGUgb25lIHdob3NlIHNraWxscyBtYXRjaCB0aGUKICByZXF1ZXN0IGFuZCBnaXZlIHRoZW0gYSBjbGVhciBicmllZi4KLSAqKlN5bnRoZXNpemUuKiogV2hlbiB0aGUgVGVhbW1hdGUgcmVwbGllcywgZm9sZCB0aGVpciBhbnN3ZXIgaW50bwogIG9uZSBjb2hlcmVudCByZXNwb25zZSB0byB0aGUgdXNlci4gVGhlIHVzZXIgc2hvdWxkbid0IGhhdmUgdG8KICBjb250ZXh0LXN3aXRjaCBiZXR3ZWVuIGFnZW50IHZvaWNlcy4KCiMjIEhvdyB0byBkZWxlZ2F0ZQoKVXNlIHRoZSBgRGVsZWdhdGVgIHRvb2wuIFRoZSBzaGFwZSBpczoKCmBgYApEZWxlZ2F0ZSh7CiAgdG86ICI8dGVhbW1hdGUta2V5PiIsICAgICAgICAgIC8vIHRoZWlyIGFnZW50IGtleSBpbiB0aGlzIHdvcmtzcGFjZQogIHByb21wdDogIjx0aGUgYWN0dWFsIGFzaz4iLCAgICAvLyB3aGF0IHlvdSB3YW50IHRoZW0gdG8gZG8KICBjb250ZXh0OiAiPG9wdGlvbmFsIHByZWFtYmxlPiIgLy8gd2hhdCB5b3UndmUgYWxyZWFkeSBsZWFybmVkIChpZiBhbnl0aGluZykKfSkKYGBgCgpUaGUgVGVhbW1hdGUgcnVucyBpbiBpdHMgb3duIGVwaGVtZXJhbCBzZXNzaW9uIGFuZCByZXR1cm5zIGl0cyBmaW5hbApyZXBseS4gWW91IHNlZSB0aGF0IHJlcGx5IGFzIHRoZSB0b29sIHJlc3VsdC4gU2VsZi1kZWxlZ2F0aW9uIGlzCnJlamVjdGVkLiBEZWxlZ2F0aW9uIGNoYWlucyBhcmUgY2FwcGVkIGF0IGRlcHRoIDMgKHlvdSDihpIgdGVhbW1hdGUg4oaSCnRoZWlyIGRlbGVnYXRpb247IG5vIGRlZXBlcikuCgojIyBSZXBvcnRpbmcKCldoZW4geW91IGFuc3dlciB0aGUgdXNlcjoKCi0gTGVhZCB3aXRoIHRoZSBhbnN3ZXIsIG5vdCB0aGUgcHJvY2Vzcy4KLSBEb24ndCBuYXJyYXRlIHdoaWNoIFRlYW1tYXRlIHlvdSBhc2tlZCB1bmxlc3MgdGhlIHVzZXIgZXhwbGljaXRseQogIGFza2VkIHdobyBkaWQgdGhlIHdvcmsuCi0gSWYgYSBkZWxlZ2F0aW9uIGZhaWxlZCwgdGVsbCB0aGUgdXNlciBwbGFpbmx5IHRoYXQgdGhlIGFuc3dlciBpc24ndAogIGF2YWlsYWJsZSBhbmQgKGJyaWVmbHkpIHdoeTogZG9uJ3QgZmFicmljYXRlLgo=';\nconst MANAGER_JSON_B64 = 'ewogICJrZXkiOiAibWFuYWdlciIsCiAgInJvbGUiOiAibWFuYWdlciIsCiAgIndlYlNlYXJjaCI6IGZhbHNlLAogICJfY29tbWVudCI6ICJJbnN0cnVjdGlvbnMgbGl2ZSBpbiBtYW5hZ2VyLm1kIChsb2FkZWQgYnkgc3JjL3RlbXBsYXRlcy50cykuIERlbGVnYXRlIGlzIGF1dG8tcmVnaXN0ZXJlZCBmb3IgYW55IHNwZWMgd2l0aCByb2xlPSdtYW5hZ2VyJyBieSB0aGUgd29ya2VycyBiYWNrZW5kOyBkZWNsYXJpbmcgaXQgaGVyZSBpcyBub3QgcmVxdWlyZWQuIgp9Cg==';\n\nexport const managerInstructions = decode(MANAGER_MD_B64);\nexport const managerSpecJson = decode(MANAGER_JSON_B64);\n"]}
package/templates.d.ts ADDED
@@ -0,0 +1,16 @@
1
+ import type { SpecInput } from './types.ts';
2
+ /** Load the kit-shipped Manager template as a ready-to-push SpecInput.
3
+ *
4
+ * Pass `overrides` to customise the spec for a specific workspace:
5
+ *
6
+ * const spec = loadManagerTemplate({ key: 'concierge', name: 'Concierge' });
7
+ * await client.specs.push(spec);
8
+ *
9
+ * Common override pairs:
10
+ * - `key`: differentiate the Manager when a workspace has multiple
11
+ * teams. Defaults to `'manager'`.
12
+ * - `instructions`: extend the base instructions with team-specific
13
+ * preamble (e.g. "Your team is the marketing team; teammates are
14
+ * writer, researcher, analyst.").
15
+ */
16
+ export declare function loadManagerTemplate(overrides?: Partial<SpecInput>): SpecInput;
package/templates.js ADDED
@@ -0,0 +1,32 @@
1
+ // SDK-shipped spec templates.
2
+ //
3
+ // Each template is a small SpecInput preset that callers can push as-is
4
+ // or extend with workspace-specific fields. The Manager template is the
5
+ // auto-spawned spec used when a team accumulates ≥2 Teammates (Phase
6
+ // 3.5). Other templates can land here as the catalog grows.
7
+ import { managerInstructions, managerSpecJson } from "./templates-inline.js";
8
+ /** Load the kit-shipped Manager template as a ready-to-push SpecInput.
9
+ *
10
+ * Pass `overrides` to customise the spec for a specific workspace:
11
+ *
12
+ * const spec = loadManagerTemplate({ key: 'concierge', name: 'Concierge' });
13
+ * await client.specs.push(spec);
14
+ *
15
+ * Common override pairs:
16
+ * - `key`: differentiate the Manager when a workspace has multiple
17
+ * teams. Defaults to `'manager'`.
18
+ * - `instructions`: extend the base instructions with team-specific
19
+ * preamble (e.g. "Your team is the marketing team; teammates are
20
+ * writer, researcher, analyst.").
21
+ */
22
+ export function loadManagerTemplate(overrides = {}) {
23
+ const parsed = JSON.parse(managerSpecJson);
24
+ return {
25
+ key: parsed.key,
26
+ role: parsed.role,
27
+ instructions: managerInstructions,
28
+ webSearch: parsed.webSearch ?? false,
29
+ ...overrides,
30
+ };
31
+ }
32
+ //# sourceMappingURL=templates.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"templates.js","sourceRoot":"","sources":["../src/templates.ts"],"names":[],"mappings":"AAAA,8BAA8B;AAC9B,EAAE;AACF,wEAAwE;AACxE,wEAAwE;AACxE,qEAAqE;AACrE,4DAA4D;AAE5D,OAAO,EAAE,mBAAmB,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAS7E;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,mBAAmB,CAClC,YAAgC,EAAE;IAElC,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,eAAe,CAAyB,CAAC;IACnE,OAAO;QACN,GAAG,EAAE,MAAM,CAAC,GAAG;QACf,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,YAAY,EAAE,mBAAmB;QACjC,SAAS,EAAE,MAAM,CAAC,SAAS,IAAI,KAAK;QACpC,GAAG,SAAS;KACZ,CAAC;AACH,CAAC","sourcesContent":["// SDK-shipped spec templates.\n//\n// Each template is a small SpecInput preset that callers can push as-is\n// or extend with workspace-specific fields. The Manager template is the\n// auto-spawned spec used when a team accumulates ≥2 Teammates (Phase\n// 3.5). Other templates can land here as the catalog grows.\n\nimport { managerInstructions, managerSpecJson } from './templates-inline.ts';\nimport type { SpecInput } from './types.ts';\n\ninterface ManagerSpecJsonShape {\n\tkey: string;\n\trole: 'manager';\n\twebSearch?: boolean;\n}\n\n/** Load the kit-shipped Manager template as a ready-to-push SpecInput.\n *\n * Pass `overrides` to customise the spec for a specific workspace:\n *\n * const spec = loadManagerTemplate({ key: 'concierge', name: 'Concierge' });\n * await client.specs.push(spec);\n *\n * Common override pairs:\n * - `key`: differentiate the Manager when a workspace has multiple\n * teams. Defaults to `'manager'`.\n * - `instructions`: extend the base instructions with team-specific\n * preamble (e.g. \"Your team is the marketing team; teammates are\n * writer, researcher, analyst.\").\n */\nexport function loadManagerTemplate(\n\toverrides: Partial<SpecInput> = {},\n): SpecInput {\n\tconst parsed = JSON.parse(managerSpecJson) as ManagerSpecJsonShape;\n\treturn {\n\t\tkey: parsed.key,\n\t\trole: parsed.role,\n\t\tinstructions: managerInstructions,\n\t\twebSearch: parsed.webSearch ?? false,\n\t\t...overrides,\n\t};\n}\n"]}
package/turn.d.ts ADDED
@@ -0,0 +1,11 @@
1
+ import type { TurnEvent } from './types.ts';
2
+ /** What `conversation.ask()` returns. */
3
+ export type Turn = Promise<string> & AsyncIterable<TurnEvent>;
4
+ /** Parse an SSE body into the events the API sends.
5
+ *
6
+ * Frames are `data: {json}` separated by blank lines. Anything else on the wire
7
+ * (comments, retry directives, a stray blank) is ignored rather than treated as
8
+ * an error: a proxy is allowed to insert keep-alive comments and a stream that
9
+ * died because of one would be maddening to debug. */
10
+ export declare function parseSSE(body: ReadableStream<Uint8Array>): AsyncGenerator<TurnEvent>;
11
+ export declare function makeTurn(response: Promise<Response>): Turn;