ccgateway 0.1.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 (75) hide show
  1. package/README.md +252 -0
  2. package/bin/ccg-dev.sh +3 -0
  3. package/dist/agents.d.ts +17 -0
  4. package/dist/agents.d.ts.map +1 -0
  5. package/dist/agents.js +45 -0
  6. package/dist/agents.js.map +1 -0
  7. package/dist/chat.d.ts +14 -0
  8. package/dist/chat.d.ts.map +1 -0
  9. package/dist/chat.js +104 -0
  10. package/dist/chat.js.map +1 -0
  11. package/dist/cli.d.ts +3 -0
  12. package/dist/cli.d.ts.map +1 -0
  13. package/dist/cli.js +501 -0
  14. package/dist/cli.js.map +1 -0
  15. package/dist/config.d.ts +53 -0
  16. package/dist/config.d.ts.map +1 -0
  17. package/dist/config.js +70 -0
  18. package/dist/config.js.map +1 -0
  19. package/dist/context.d.ts +45 -0
  20. package/dist/context.d.ts.map +1 -0
  21. package/dist/context.js +201 -0
  22. package/dist/context.js.map +1 -0
  23. package/dist/daemon.d.ts +27 -0
  24. package/dist/daemon.d.ts.map +1 -0
  25. package/dist/daemon.js +207 -0
  26. package/dist/daemon.js.map +1 -0
  27. package/dist/heartbeat.d.ts +42 -0
  28. package/dist/heartbeat.d.ts.map +1 -0
  29. package/dist/heartbeat.js +153 -0
  30. package/dist/heartbeat.js.map +1 -0
  31. package/dist/logger.d.ts +15 -0
  32. package/dist/logger.d.ts.map +1 -0
  33. package/dist/logger.js +70 -0
  34. package/dist/logger.js.map +1 -0
  35. package/dist/messaging.d.ts +43 -0
  36. package/dist/messaging.d.ts.map +1 -0
  37. package/dist/messaging.js +132 -0
  38. package/dist/messaging.js.map +1 -0
  39. package/dist/migrate.d.ts +24 -0
  40. package/dist/migrate.d.ts.map +1 -0
  41. package/dist/migrate.js +356 -0
  42. package/dist/migrate.js.map +1 -0
  43. package/dist/plugin.d.ts +63 -0
  44. package/dist/plugin.d.ts.map +1 -0
  45. package/dist/plugin.js +93 -0
  46. package/dist/plugin.js.map +1 -0
  47. package/dist/plugins/discord-gateway.d.ts +32 -0
  48. package/dist/plugins/discord-gateway.d.ts.map +1 -0
  49. package/dist/plugins/discord-gateway.js +208 -0
  50. package/dist/plugins/discord-gateway.js.map +1 -0
  51. package/dist/plugins/slack-gateway.d.ts +35 -0
  52. package/dist/plugins/slack-gateway.d.ts.map +1 -0
  53. package/dist/plugins/slack-gateway.js +291 -0
  54. package/dist/plugins/slack-gateway.js.map +1 -0
  55. package/dist/router.d.ts +44 -0
  56. package/dist/router.d.ts.map +1 -0
  57. package/dist/router.js +103 -0
  58. package/dist/router.js.map +1 -0
  59. package/dist/sessions.d.ts +55 -0
  60. package/dist/sessions.d.ts.map +1 -0
  61. package/dist/sessions.js +160 -0
  62. package/dist/sessions.js.map +1 -0
  63. package/dist/skills.d.ts +58 -0
  64. package/dist/skills.d.ts.map +1 -0
  65. package/dist/skills.js +194 -0
  66. package/dist/skills.js.map +1 -0
  67. package/dist/spawner.d.ts +29 -0
  68. package/dist/spawner.d.ts.map +1 -0
  69. package/dist/spawner.js +54 -0
  70. package/dist/spawner.js.map +1 -0
  71. package/dist/types.d.ts +22 -0
  72. package/dist/types.d.ts.map +1 -0
  73. package/dist/types.js +4 -0
  74. package/dist/types.js.map +1 -0
  75. package/package.json +48 -0
package/dist/router.js ADDED
@@ -0,0 +1,103 @@
1
+ // ── MessageRouter ─────────────────────────────────────────────────────────
2
+ export class MessageRouter {
3
+ agents;
4
+ sessions;
5
+ context;
6
+ spawner;
7
+ bindings;
8
+ constructor(agents, sessions, context, spawner, bindings) {
9
+ this.agents = agents;
10
+ this.sessions = sessions;
11
+ this.context = context;
12
+ this.spawner = spawner;
13
+ this.bindings = bindings;
14
+ }
15
+ /**
16
+ * Resolve which agent handles a message based on bindings.
17
+ * Given (gateway, channelId), find the matching binding and return binding.agent.
18
+ */
19
+ resolveAgent(gateway, channelId) {
20
+ const binding = this.bindings.find((b) => b.gateway === gateway && b.channel === channelId);
21
+ return binding?.agent;
22
+ }
23
+ /**
24
+ * Full message dispatch pipeline.
25
+ *
26
+ * 1. Look up agent config from registry
27
+ * 2. Derive session key: {agentId}:{gateway}:{channel}
28
+ * 3. Get or create session
29
+ * 4. Append user message to session
30
+ * 5. Build context
31
+ * 6. Spawn claude --print
32
+ * 7. Append assistant response to session (or error on failure)
33
+ * 8. Return response text
34
+ */
35
+ async route(message) {
36
+ const agentId = message.to.agent;
37
+ // 1. Get agent config
38
+ const agent = this.agents.getAgent(agentId);
39
+ if (!agent) {
40
+ throw new Error(`Agent "${agentId}" not found in registry`);
41
+ }
42
+ // 2. Derive session key
43
+ const sessionKey = this.sessions.getOrCreateSession(agentId, message.from.gateway, message.from.channel);
44
+ // 3. Append user message to session
45
+ await this.sessions.appendMessage(agentId, sessionKey, {
46
+ role: "user",
47
+ content: message.content,
48
+ ts: Date.now(),
49
+ source: message.from.gateway,
50
+ sourceUser: message.from.user,
51
+ sourceMessageId: message.from.messageId,
52
+ });
53
+ // 4. Build context
54
+ const systemPrompt = await this.context.build(agentId, sessionKey);
55
+ // 5. Spawn claude --print
56
+ const result = await this.spawner.spawn({
57
+ workspace: agent.workspace,
58
+ message: message.content,
59
+ systemPrompt,
60
+ model: agent.model,
61
+ allowedTools: agent.allowedTools,
62
+ });
63
+ // 6. Handle failure: append error to session and throw
64
+ if (result.exitCode !== 0) {
65
+ const errorContent = result.response || `Spawner failed with exit code ${result.exitCode}`;
66
+ await this.sessions.appendMessage(agentId, sessionKey, {
67
+ role: "assistant",
68
+ content: `[error] ${errorContent}`,
69
+ ts: Date.now(),
70
+ tokens: result.tokensEstimate,
71
+ });
72
+ throw new Error(`Spawner exited with code ${result.exitCode}: ${errorContent}`);
73
+ }
74
+ // 7. Append assistant response to session
75
+ await this.sessions.appendMessage(agentId, sessionKey, {
76
+ role: "assistant",
77
+ content: result.response,
78
+ ts: Date.now(),
79
+ tokens: result.tokensEstimate,
80
+ });
81
+ // 8. Return response text
82
+ return result.response;
83
+ }
84
+ /**
85
+ * Add a binding at runtime.
86
+ */
87
+ addBinding(binding) {
88
+ this.bindings.push(binding);
89
+ }
90
+ /**
91
+ * Get all bindings for a given agent.
92
+ */
93
+ getBindingsForAgent(agentId) {
94
+ return this.bindings.filter((b) => b.agent === agentId);
95
+ }
96
+ /**
97
+ * Get the primary (first) binding for an agent.
98
+ */
99
+ getPrimaryBinding(agentId) {
100
+ return this.bindings.find((b) => b.agent === agentId);
101
+ }
102
+ }
103
+ //# sourceMappingURL=router.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"router.js","sourceRoot":"","sources":["../src/router.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,55 @@
1
+ export interface SessionMessage {
2
+ role: "user" | "assistant" | "system";
3
+ content: string;
4
+ ts: number;
5
+ source?: string;
6
+ sourceUser?: string;
7
+ sourceMessageId?: string;
8
+ tokens?: {
9
+ in: number;
10
+ out: number;
11
+ };
12
+ }
13
+ export interface SessionInfo {
14
+ agentId: string;
15
+ sessionKey: string;
16
+ messageCount: number;
17
+ lastActivity: number;
18
+ filePath: string;
19
+ }
20
+ export declare class SessionManager {
21
+ private ccgHome;
22
+ constructor(ccgHome: string);
23
+ /**
24
+ * Get or create a session. Returns the session key.
25
+ */
26
+ getOrCreateSession(agentId: string, source: string, sourceId: string): string;
27
+ /**
28
+ * Get the JSONL file path for a session.
29
+ */
30
+ getSessionPath(agentId: string, sessionKey: string): string;
31
+ /**
32
+ * Append a message to the session JSONL.
33
+ */
34
+ appendMessage(agentId: string, sessionKey: string, message: SessionMessage): Promise<void>;
35
+ /**
36
+ * Read all messages from a session.
37
+ * Returns an empty array for non-existent sessions.
38
+ */
39
+ readHistory(agentId: string, sessionKey: string): Promise<SessionMessage[]>;
40
+ /**
41
+ * Build windowed history that fits within token budget.
42
+ * Estimates tokens as chars/4. Returns newest messages that fit.
43
+ * tokenBudget defaults to 200000.
44
+ */
45
+ getWindowedHistory(agentId: string, sessionKey: string, tokenBudget?: number): Promise<SessionMessage[]>;
46
+ /**
47
+ * Reset session: archive current JSONL (rename with timestamp suffix).
48
+ */
49
+ resetSession(agentId: string, sessionKey: string): Promise<void>;
50
+ /**
51
+ * List all sessions, optionally filtered by agent.
52
+ */
53
+ listSessions(agentId?: string): Promise<SessionInfo[]>;
54
+ }
55
+ //# sourceMappingURL=sessions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sessions.d.ts","sourceRoot":"","sources":["../src/sessions.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,QAAQ,CAAC;IACtC,OAAO,EAAE,MAAM,CAAC;IAChB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,MAAM,CAAC,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC;CACtC;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAqCD,qBAAa,cAAc;IACzB,OAAO,CAAC,OAAO,CAAS;gBAEZ,OAAO,EAAE,MAAM;IAI3B;;OAEG;IACH,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM;IAI7E;;OAEG;IACH,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM;IAU3D;;OAEG;IACG,aAAa,CACjB,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,IAAI,CAAC;IAYhB;;;OAGG;IACG,WAAW,CACf,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,cAAc,EAAE,CAAC;IAY5B;;;;OAIG;IACG,kBAAkB,CACtB,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,EAClB,WAAW,GAAE,MAAe,GAC3B,OAAO,CAAC,cAAc,EAAE,CAAC;IAiC5B;;OAEG;IACG,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAYtE;;OAEG;IACG,YAAY,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;CA8C7D"}
@@ -0,0 +1,160 @@
1
+ import { appendFile, readFile, rename, readdir, mkdir, stat } from "node:fs/promises";
2
+ import { existsSync } from "node:fs";
3
+ import { join } from "node:path";
4
+ // ── Helpers ────────────────────────────────────────────────────────────────
5
+ /**
6
+ * Convert a session key (with colons) to a filesystem-safe filename stem.
7
+ * e.g. "salt:discord:1465736400014938230" → "salt-discord-1465736400014938230"
8
+ */
9
+ function keyToFilename(sessionKey) {
10
+ return sessionKey.replace(/:/g, "-") + ".jsonl";
11
+ }
12
+ /**
13
+ * Convert a filesystem filename back to a session key.
14
+ * e.g. "salt-discord-1465736400014938230.jsonl" → "salt:discord:1465736400014938230"
15
+ * The key format is {agentId}:{source}:{sourceId}. We know the agentId from context,
16
+ * so we can reconstruct by replacing the first two dashes with colons.
17
+ */
18
+ function filenameToKey(filename) {
19
+ const stem = filename.replace(/\.jsonl$/, "");
20
+ // Replace first dash with colon, then second dash with colon.
21
+ // The sourceId portion may itself contain dashes, so only replace first two.
22
+ const first = stem.indexOf("-");
23
+ if (first === -1)
24
+ return stem;
25
+ const second = stem.indexOf("-", first + 1);
26
+ if (second === -1)
27
+ return stem;
28
+ return (stem.slice(0, first) +
29
+ ":" +
30
+ stem.slice(first + 1, second) +
31
+ ":" +
32
+ stem.slice(second + 1));
33
+ }
34
+ // ── SessionManager ─────────────────────────────────────────────────────────
35
+ export class SessionManager {
36
+ ccgHome;
37
+ constructor(ccgHome) {
38
+ this.ccgHome = ccgHome;
39
+ }
40
+ /**
41
+ * Get or create a session. Returns the session key.
42
+ */
43
+ getOrCreateSession(agentId, source, sourceId) {
44
+ return `${agentId}:${source}:${sourceId}`;
45
+ }
46
+ /**
47
+ * Get the JSONL file path for a session.
48
+ */
49
+ getSessionPath(agentId, sessionKey) {
50
+ return join(this.ccgHome, "agents", agentId, "sessions", keyToFilename(sessionKey));
51
+ }
52
+ /**
53
+ * Append a message to the session JSONL.
54
+ */
55
+ async appendMessage(agentId, sessionKey, message) {
56
+ const filePath = this.getSessionPath(agentId, sessionKey);
57
+ const dir = join(this.ccgHome, "agents", agentId, "sessions");
58
+ if (!existsSync(dir)) {
59
+ await mkdir(dir, { recursive: true });
60
+ }
61
+ const line = JSON.stringify(message) + "\n";
62
+ await appendFile(filePath, line, "utf-8");
63
+ }
64
+ /**
65
+ * Read all messages from a session.
66
+ * Returns an empty array for non-existent sessions.
67
+ */
68
+ async readHistory(agentId, sessionKey) {
69
+ const filePath = this.getSessionPath(agentId, sessionKey);
70
+ if (!existsSync(filePath)) {
71
+ return [];
72
+ }
73
+ const raw = await readFile(filePath, "utf-8");
74
+ const lines = raw.split("\n").filter((l) => l.trim().length > 0);
75
+ return lines.map((line) => JSON.parse(line));
76
+ }
77
+ /**
78
+ * Build windowed history that fits within token budget.
79
+ * Estimates tokens as chars/4. Returns newest messages that fit.
80
+ * tokenBudget defaults to 200000.
81
+ */
82
+ async getWindowedHistory(agentId, sessionKey, tokenBudget = 200000) {
83
+ const messages = await this.readHistory(agentId, sessionKey);
84
+ if (messages.length === 0) {
85
+ return [];
86
+ }
87
+ // Always keep at least the most recent message
88
+ const result = [];
89
+ let totalTokens = 0;
90
+ // Walk backwards from newest to oldest
91
+ for (let i = messages.length - 1; i >= 0; i--) {
92
+ const msgTokens = Math.ceil(messages[i].content.length / 4);
93
+ if (result.length === 0) {
94
+ // Always include the most recent message
95
+ result.unshift(messages[i]);
96
+ totalTokens += msgTokens;
97
+ continue;
98
+ }
99
+ if (totalTokens + msgTokens <= tokenBudget) {
100
+ result.unshift(messages[i]);
101
+ totalTokens += msgTokens;
102
+ }
103
+ else {
104
+ break;
105
+ }
106
+ }
107
+ return result;
108
+ }
109
+ /**
110
+ * Reset session: archive current JSONL (rename with timestamp suffix).
111
+ */
112
+ async resetSession(agentId, sessionKey) {
113
+ const filePath = this.getSessionPath(agentId, sessionKey);
114
+ if (!existsSync(filePath)) {
115
+ return;
116
+ }
117
+ const timestamp = Date.now();
118
+ const archivePath = filePath.replace(/\.jsonl$/, `.${timestamp}.jsonl`);
119
+ await rename(filePath, archivePath);
120
+ }
121
+ /**
122
+ * List all sessions, optionally filtered by agent.
123
+ */
124
+ async listSessions(agentId) {
125
+ const agentsDir = join(this.ccgHome, "agents");
126
+ const results = [];
127
+ if (!existsSync(agentsDir)) {
128
+ return results;
129
+ }
130
+ const agentDirs = agentId ? [agentId] : await readdir(agentsDir);
131
+ for (const agent of agentDirs) {
132
+ const sessionsDir = join(agentsDir, agent, "sessions");
133
+ if (!existsSync(sessionsDir)) {
134
+ continue;
135
+ }
136
+ const files = await readdir(sessionsDir);
137
+ for (const file of files) {
138
+ // Only match active session files (not archived ones with timestamp suffix)
139
+ if (!file.endsWith(".jsonl") || /\.\d+\.jsonl$/.test(file)) {
140
+ continue;
141
+ }
142
+ const filePath = join(sessionsDir, file);
143
+ const sessionKey = filenameToKey(file);
144
+ const messages = await this.readHistory(agent, sessionKey);
145
+ const lastActivity = messages.length > 0
146
+ ? messages[messages.length - 1].ts
147
+ : (await stat(filePath)).mtimeMs;
148
+ results.push({
149
+ agentId: agent,
150
+ sessionKey,
151
+ messageCount: messages.length,
152
+ lastActivity,
153
+ filePath,
154
+ });
155
+ }
156
+ }
157
+ return results;
158
+ }
159
+ }
160
+ //# sourceMappingURL=sessions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sessions.js","sourceRoot":"","sources":["../src/sessions.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,58 @@
1
+ export interface SkillDefinition {
2
+ name: string;
3
+ description: string;
4
+ type: "markdown" | "native";
5
+ filePath?: string;
6
+ agentId?: string;
7
+ }
8
+ /**
9
+ * Parse YAML frontmatter from a markdown skill file.
10
+ * Expects `---` delimiters at the top with `name:` and `description:` fields.
11
+ * Simple parser — no yaml dependency.
12
+ */
13
+ export declare function parseFrontmatter(content: string): {
14
+ name: string;
15
+ description: string;
16
+ } | null;
17
+ export declare class SkillManager {
18
+ private ccgHome;
19
+ constructor(ccgHome: string);
20
+ private sharedSkillsDir;
21
+ private agentSkillsDir;
22
+ /**
23
+ * Discover all skills: shared + agent-specific.
24
+ * Agent-specific skills override shared skills with the same name.
25
+ */
26
+ discoverSkills(agentId?: string): Promise<SkillDefinition[]>;
27
+ /**
28
+ * Read a markdown skill's full content.
29
+ * Checks agent-specific dir first (if agentId provided), then shared.
30
+ */
31
+ readSkill(name: string, agentId?: string): Promise<string | null>;
32
+ /**
33
+ * Build skill index for context injection (name + description per skill).
34
+ */
35
+ buildSkillIndex(agentId?: string): Promise<string>;
36
+ /**
37
+ * Add a skill (copy .md file to shared or agent-specific directory).
38
+ */
39
+ addSkill(filePath: string, agentId?: string): Promise<void>;
40
+ /**
41
+ * Remove a skill.
42
+ */
43
+ removeSkill(name: string, agentId?: string): Promise<boolean>;
44
+ /**
45
+ * List skills.
46
+ */
47
+ listSkills(agentId?: string): Promise<SkillDefinition[]>;
48
+ /**
49
+ * Load all markdown skills from a directory.
50
+ */
51
+ private loadSkillsFromDir;
52
+ /**
53
+ * Find a skill file in a directory by skill name.
54
+ * Reads frontmatter of each .md file to match by name.
55
+ */
56
+ private findSkillFile;
57
+ }
58
+ //# sourceMappingURL=skills.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skills.d.ts","sourceRoot":"","sources":["../src/skills.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,UAAU,GAAG,QAAQ,CAAC;IAC5B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAID;;;;GAIG;AACH,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,MAAM,GACd;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAoC9C;AAID,qBAAa,YAAY;IACvB,OAAO,CAAC,OAAO,CAAS;gBAEZ,OAAO,EAAE,MAAM;IAM3B,OAAO,CAAC,eAAe;IAIvB,OAAO,CAAC,cAAc;IAMtB;;;OAGG;IACG,cAAc,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC;IAuBlE;;;OAGG;IACG,SAAS,CACb,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAqBzB;;OAEG;IACG,eAAe,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAexD;;OAEG;IACG,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAcjE;;OAEG;IACG,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAYnE;;OAEG;IACG,UAAU,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC;IAM9D;;OAEG;YACW,iBAAiB;IAiC/B;;;OAGG;YACW,aAAa;CAsB5B"}
package/dist/skills.js ADDED
@@ -0,0 +1,194 @@
1
+ import { readFile, readdir, mkdir, copyFile, unlink } from "node:fs/promises";
2
+ import { existsSync } from "node:fs";
3
+ import { join, basename } from "node:path";
4
+ // ── Frontmatter parser ──────────────────────────────────────────────────────
5
+ /**
6
+ * Parse YAML frontmatter from a markdown skill file.
7
+ * Expects `---` delimiters at the top with `name:` and `description:` fields.
8
+ * Simple parser — no yaml dependency.
9
+ */
10
+ export function parseFrontmatter(content) {
11
+ const lines = content.split("\n");
12
+ // Must start with ---
13
+ if (lines[0]?.trim() !== "---")
14
+ return null;
15
+ let endIndex = -1;
16
+ for (let i = 1; i < lines.length; i++) {
17
+ if (lines[i].trim() === "---") {
18
+ endIndex = i;
19
+ break;
20
+ }
21
+ }
22
+ if (endIndex === -1)
23
+ return null;
24
+ let name = "";
25
+ let description = "";
26
+ for (let i = 1; i < endIndex; i++) {
27
+ const line = lines[i];
28
+ const nameMatch = line.match(/^name:\s*(.+)/);
29
+ if (nameMatch) {
30
+ name = nameMatch[1].trim();
31
+ continue;
32
+ }
33
+ const descMatch = line.match(/^description:\s*(.+)/);
34
+ if (descMatch) {
35
+ description = descMatch[1].trim();
36
+ continue;
37
+ }
38
+ }
39
+ if (!name)
40
+ return null;
41
+ return { name, description };
42
+ }
43
+ // ── SkillManager ────────────────────────────────────────────────────────────
44
+ export class SkillManager {
45
+ ccgHome;
46
+ constructor(ccgHome) {
47
+ this.ccgHome = ccgHome;
48
+ }
49
+ // ── Directory helpers ───────────────────────────────────────────────────
50
+ sharedSkillsDir() {
51
+ return join(this.ccgHome, "skills");
52
+ }
53
+ agentSkillsDir(agentId) {
54
+ return join(this.ccgHome, "agents", agentId, "skills");
55
+ }
56
+ // ── Core methods ────────────────────────────────────────────────────────
57
+ /**
58
+ * Discover all skills: shared + agent-specific.
59
+ * Agent-specific skills override shared skills with the same name.
60
+ */
61
+ async discoverSkills(agentId) {
62
+ const skillMap = new Map();
63
+ // Load shared skills first
64
+ const sharedSkills = await this.loadSkillsFromDir(this.sharedSkillsDir());
65
+ for (const skill of sharedSkills) {
66
+ skillMap.set(skill.name, skill);
67
+ }
68
+ // Load agent-specific skills (override shared)
69
+ if (agentId) {
70
+ const agentSkills = await this.loadSkillsFromDir(this.agentSkillsDir(agentId), agentId);
71
+ for (const skill of agentSkills) {
72
+ skillMap.set(skill.name, skill);
73
+ }
74
+ }
75
+ return Array.from(skillMap.values());
76
+ }
77
+ /**
78
+ * Read a markdown skill's full content.
79
+ * Checks agent-specific dir first (if agentId provided), then shared.
80
+ */
81
+ async readSkill(name, agentId) {
82
+ // Check agent-specific first
83
+ if (agentId) {
84
+ const agentPath = await this.findSkillFile(this.agentSkillsDir(agentId), name);
85
+ if (agentPath) {
86
+ return readFile(agentPath, "utf-8");
87
+ }
88
+ }
89
+ // Fall back to shared
90
+ const sharedPath = await this.findSkillFile(this.sharedSkillsDir(), name);
91
+ if (sharedPath) {
92
+ return readFile(sharedPath, "utf-8");
93
+ }
94
+ return null;
95
+ }
96
+ /**
97
+ * Build skill index for context injection (name + description per skill).
98
+ */
99
+ async buildSkillIndex(agentId) {
100
+ const skills = await this.discoverSkills(agentId);
101
+ if (skills.length === 0) {
102
+ return "--- Available Skills ---\n(none)";
103
+ }
104
+ const lines = skills.map((s) => {
105
+ const tag = s.type === "native" ? " [native]" : "";
106
+ return `- ${s.name}: ${s.description}${tag}`;
107
+ });
108
+ return `--- Available Skills ---\n${lines.join("\n")}`;
109
+ }
110
+ /**
111
+ * Add a skill (copy .md file to shared or agent-specific directory).
112
+ */
113
+ async addSkill(filePath, agentId) {
114
+ const targetDir = agentId
115
+ ? this.agentSkillsDir(agentId)
116
+ : this.sharedSkillsDir();
117
+ if (!existsSync(targetDir)) {
118
+ await mkdir(targetDir, { recursive: true });
119
+ }
120
+ const fileName = basename(filePath);
121
+ const targetPath = join(targetDir, fileName);
122
+ await copyFile(filePath, targetPath);
123
+ }
124
+ /**
125
+ * Remove a skill.
126
+ */
127
+ async removeSkill(name, agentId) {
128
+ const targetDir = agentId
129
+ ? this.agentSkillsDir(agentId)
130
+ : this.sharedSkillsDir();
131
+ const filePath = await this.findSkillFile(targetDir, name);
132
+ if (!filePath)
133
+ return false;
134
+ await unlink(filePath);
135
+ return true;
136
+ }
137
+ /**
138
+ * List skills.
139
+ */
140
+ async listSkills(agentId) {
141
+ return this.discoverSkills(agentId);
142
+ }
143
+ // ── Private helpers ─────────────────────────────────────────────────────
144
+ /**
145
+ * Load all markdown skills from a directory.
146
+ */
147
+ async loadSkillsFromDir(dir, agentId) {
148
+ if (!existsSync(dir))
149
+ return [];
150
+ const entries = await readdir(dir);
151
+ const skills = [];
152
+ for (const entry of entries) {
153
+ if (!entry.endsWith(".md"))
154
+ continue;
155
+ const filePath = join(dir, entry);
156
+ const content = await readFile(filePath, "utf-8");
157
+ const meta = parseFrontmatter(content);
158
+ if (meta) {
159
+ const skill = {
160
+ name: meta.name,
161
+ description: meta.description,
162
+ type: "markdown",
163
+ filePath,
164
+ };
165
+ if (agentId) {
166
+ skill.agentId = agentId;
167
+ }
168
+ skills.push(skill);
169
+ }
170
+ }
171
+ return skills;
172
+ }
173
+ /**
174
+ * Find a skill file in a directory by skill name.
175
+ * Reads frontmatter of each .md file to match by name.
176
+ */
177
+ async findSkillFile(dir, name) {
178
+ if (!existsSync(dir))
179
+ return null;
180
+ const entries = await readdir(dir);
181
+ for (const entry of entries) {
182
+ if (!entry.endsWith(".md"))
183
+ continue;
184
+ const filePath = join(dir, entry);
185
+ const content = await readFile(filePath, "utf-8");
186
+ const meta = parseFrontmatter(content);
187
+ if (meta && meta.name === name) {
188
+ return filePath;
189
+ }
190
+ }
191
+ return null;
192
+ }
193
+ }
194
+ //# sourceMappingURL=skills.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skills.js","sourceRoot":"","sources":["../src/skills.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ export interface SpawnResult {
2
+ response: string;
3
+ exitCode: number;
4
+ tokensEstimate: {
5
+ in: number;
6
+ out: number;
7
+ };
8
+ }
9
+ export interface SpawnOptions {
10
+ workspace: string;
11
+ message: string;
12
+ systemPrompt: string;
13
+ model: string;
14
+ allowedTools: string[];
15
+ timeoutMs?: number;
16
+ }
17
+ export declare class CCSpawner {
18
+ /**
19
+ * Spawn a `claude --print` invocation.
20
+ *
21
+ * Executes:
22
+ * claude --print -p "<message>" --append-system-prompt "<context>"
23
+ * --model <model> --allowedTools Tool1,Tool2,...
24
+ *
25
+ * Captures stdout as the response. Estimates tokens as chars / 4.
26
+ */
27
+ spawn(options: SpawnOptions): Promise<SpawnResult>;
28
+ }
29
+ //# sourceMappingURL=spawner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spawner.d.ts","sourceRoot":"","sources":["../src/spawner.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC;CAC7C;AAED,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAMD,qBAAa,SAAS;IACpB;;;;;;;;OAQG;IACG,KAAK,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC;CAwDzD"}