@sylix/coworker 1.2.6 → 1.3.1

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 (82) hide show
  1. package/dist/cli/index.d.ts.map +1 -1
  2. package/dist/cli/index.js +181 -106
  3. package/dist/cli/index.js.map +1 -1
  4. package/dist/commands/slash/advanced.d.ts +3 -0
  5. package/dist/commands/slash/advanced.d.ts.map +1 -0
  6. package/dist/commands/slash/advanced.js +225 -0
  7. package/dist/commands/slash/advanced.js.map +1 -0
  8. package/dist/commands/slash/config.d.ts +3 -0
  9. package/dist/commands/slash/config.d.ts.map +1 -0
  10. package/dist/commands/slash/config.js +161 -0
  11. package/dist/commands/slash/config.js.map +1 -0
  12. package/dist/commands/slash/context.d.ts +3 -0
  13. package/dist/commands/slash/context.d.ts.map +1 -0
  14. package/dist/commands/slash/context.js +127 -0
  15. package/dist/commands/slash/context.js.map +1 -0
  16. package/dist/commands/slash/core.d.ts +3 -0
  17. package/dist/commands/slash/core.d.ts.map +1 -0
  18. package/dist/commands/slash/core.js +112 -0
  19. package/dist/commands/slash/core.js.map +1 -0
  20. package/dist/commands/slash/developer.d.ts +3 -0
  21. package/dist/commands/slash/developer.d.ts.map +1 -0
  22. package/dist/commands/slash/developer.js +174 -0
  23. package/dist/commands/slash/developer.js.map +1 -0
  24. package/dist/commands/slash/files.d.ts +3 -0
  25. package/dist/commands/slash/files.d.ts.map +1 -0
  26. package/dist/commands/slash/files.js +216 -0
  27. package/dist/commands/slash/files.js.map +1 -0
  28. package/dist/commands/slash/registry.d.ts +36 -0
  29. package/dist/commands/slash/registry.d.ts.map +1 -0
  30. package/dist/commands/slash/registry.js +69 -0
  31. package/dist/commands/slash/registry.js.map +1 -0
  32. package/dist/commands/slash/session.d.ts +3 -0
  33. package/dist/commands/slash/session.d.ts.map +1 -0
  34. package/dist/commands/slash/session.js +144 -0
  35. package/dist/commands/slash/session.js.map +1 -0
  36. package/dist/core/CoWorkerAgent.d.ts +8 -2
  37. package/dist/core/CoWorkerAgent.d.ts.map +1 -1
  38. package/dist/core/CoWorkerAgent.js +179 -36
  39. package/dist/core/CoWorkerAgent.js.map +1 -1
  40. package/dist/review/CodeReviewEngine.d.ts +78 -0
  41. package/dist/review/CodeReviewEngine.d.ts.map +1 -0
  42. package/dist/review/CodeReviewEngine.js +449 -0
  43. package/dist/review/CodeReviewEngine.js.map +1 -0
  44. package/dist/session/SessionManager.js +10 -5
  45. package/dist/session/SessionManager.js.map +1 -1
  46. package/dist/skills/HookAndSkillManager.d.ts +29 -5
  47. package/dist/skills/HookAndSkillManager.d.ts.map +1 -1
  48. package/dist/skills/HookAndSkillManager.js +167 -12
  49. package/dist/skills/HookAndSkillManager.js.map +1 -1
  50. package/dist/todos/TodoManager.d.ts +19 -0
  51. package/dist/todos/TodoManager.d.ts.map +1 -0
  52. package/dist/todos/TodoManager.js +102 -0
  53. package/dist/todos/TodoManager.js.map +1 -0
  54. package/dist/tools/NativeTools.d.ts +98 -0
  55. package/dist/tools/NativeTools.d.ts.map +1 -1
  56. package/dist/tools/NativeTools.js +571 -0
  57. package/dist/tools/NativeTools.js.map +1 -1
  58. package/dist/tools/Schemas.d.ts +1199 -102
  59. package/dist/tools/Schemas.d.ts.map +1 -1
  60. package/dist/tools/Schemas.js +358 -40
  61. package/dist/tools/Schemas.js.map +1 -1
  62. package/dist/utils/conversations.d.ts +14 -0
  63. package/dist/utils/conversations.d.ts.map +1 -0
  64. package/dist/utils/conversations.js +100 -0
  65. package/dist/utils/conversations.js.map +1 -0
  66. package/dist/utils/inputbar.d.ts +87 -0
  67. package/dist/utils/inputbar.d.ts.map +1 -0
  68. package/dist/utils/inputbar.js +263 -0
  69. package/dist/utils/inputbar.js.map +1 -0
  70. package/dist/utils/output.d.ts +73 -48
  71. package/dist/utils/output.d.ts.map +1 -1
  72. package/dist/utils/output.js +349 -158
  73. package/dist/utils/output.js.map +1 -1
  74. package/dist/utils/palette.d.ts +25 -0
  75. package/dist/utils/palette.d.ts.map +1 -0
  76. package/dist/utils/palette.js +92 -0
  77. package/dist/utils/palette.js.map +1 -0
  78. package/dist/utils/welcome.d.ts +2 -0
  79. package/dist/utils/welcome.d.ts.map +1 -0
  80. package/dist/utils/welcome.js +130 -0
  81. package/dist/utils/welcome.js.map +1 -0
  82. package/package.json +1 -1
@@ -0,0 +1,69 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.COMMANDS = void 0;
4
+ exports.setCommandContext = setCommandContext;
5
+ exports.getCommandContext = getCommandContext;
6
+ exports.resolveCommand = resolveCommand;
7
+ exports.filterCommands = filterCommands;
8
+ exports.getGroups = getGroups;
9
+ exports.getGroupCommands = getGroupCommands;
10
+ // Global context set at CLI boot
11
+ let _ctx = null;
12
+ function setCommandContext(ctx) { _ctx = ctx; }
13
+ function getCommandContext() { return _ctx; }
14
+ // ============================================================================
15
+ // COMMAND REGISTRY — import all groups and merge
16
+ // ============================================================================
17
+ const core_1 = require("./core");
18
+ const files_1 = require("./files");
19
+ const context_1 = require("./context");
20
+ const session_1 = require("./session");
21
+ const config_1 = require("./config");
22
+ const developer_1 = require("./developer");
23
+ const advanced_1 = require("./advanced");
24
+ exports.COMMANDS = [
25
+ ...core_1.coreCommands,
26
+ ...files_1.fileCommands,
27
+ ...context_1.contextCommands,
28
+ ...session_1.sessionCommands,
29
+ ...config_1.configCommands,
30
+ ...developer_1.developerCommands,
31
+ ...advanced_1.advancedCommands,
32
+ ];
33
+ /**
34
+ * Resolve a slash command by name or alias.
35
+ */
36
+ function resolveCommand(input) {
37
+ const name = input.startsWith('/') ? input.slice(1).split(' ')[0] : input.split(' ')[0];
38
+ return exports.COMMANDS.find(c => c.name === name || c.aliases?.includes(name));
39
+ }
40
+ /**
41
+ * Filter commands by partial name (for autocomplete).
42
+ */
43
+ function filterCommands(partial) {
44
+ const q = partial.toLowerCase().replace(/^\//, '');
45
+ if (!q)
46
+ return exports.COMMANDS;
47
+ return exports.COMMANDS.filter(c => c.name.includes(q) || c.description.toLowerCase().includes(q));
48
+ }
49
+ /**
50
+ * Get unique group names in order.
51
+ */
52
+ function getGroups() {
53
+ const seen = new Set();
54
+ const groups = [];
55
+ for (const c of exports.COMMANDS) {
56
+ if (!seen.has(c.group)) {
57
+ seen.add(c.group);
58
+ groups.push(c.group);
59
+ }
60
+ }
61
+ return groups;
62
+ }
63
+ /**
64
+ * Get commands in a specific group.
65
+ */
66
+ function getGroupCommands(group) {
67
+ return exports.COMMANDS.filter(c => c.group === group);
68
+ }
69
+ //# sourceMappingURL=registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../../src/commands/slash/registry.ts"],"names":[],"mappings":";;;AAqBA,8CAA4E;AAC5E,8CAA2E;AA2B3E,wCAGC;AAKD,wCAMC;AAKD,8BAUC;AAKD,4CAEC;AAlED,iCAAiC;AACjC,IAAI,IAAI,GAA0B,IAAI,CAAC;AACvC,SAAgB,iBAAiB,CAAC,GAAmB,IAAU,IAAI,GAAG,GAAG,CAAC,CAAC,CAAC;AAC5E,SAAgB,iBAAiB,KAA4B,OAAO,IAAI,CAAC,CAAC,CAAC;AAE3E,+EAA+E;AAC/E,iDAAiD;AACjD,+EAA+E;AAE/E,iCAAsC;AACtC,mCAAuC;AACvC,uCAA4C;AAC5C,uCAA4C;AAC5C,qCAA0C;AAC1C,2CAAgD;AAChD,yCAA8C;AAEjC,QAAA,QAAQ,GAAmB;IACtC,GAAG,mBAAY;IACf,GAAG,oBAAY;IACf,GAAG,yBAAe;IAClB,GAAG,yBAAe;IAClB,GAAG,uBAAc;IACjB,GAAG,6BAAiB;IACpB,GAAG,2BAAgB;CACpB,CAAC;AAEF;;GAEG;AACH,SAAgB,cAAc,CAAC,KAAa;IAC1C,MAAM,IAAI,GAAG,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IACxF,OAAO,gBAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,IAAI,CAAC,CAAC,OAAO,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;AAC1E,CAAC;AAED;;GAEG;AACH,SAAgB,cAAc,CAAC,OAAe;IAC5C,MAAM,CAAC,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IACnD,IAAI,CAAC,CAAC;QAAE,OAAO,gBAAQ,CAAC;IACxB,OAAO,gBAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CACzB,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,WAAW,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,CAC9D,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,SAAgB,SAAS;IACvB,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,KAAK,MAAM,CAAC,IAAI,gBAAQ,EAAE,CAAC;QACzB,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC;YACvB,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;YAClB,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;QACvB,CAAC;IACH,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;GAEG;AACH,SAAgB,gBAAgB,CAAC,KAAa;IAC5C,OAAO,gBAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,KAAK,CAAC,CAAC;AACjD,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { SlashCommand } from './registry';
2
+ export declare const sessionCommands: SlashCommand[];
3
+ //# sourceMappingURL=session.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../../src/commands/slash/session.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAK1C,eAAO,MAAM,eAAe,EAAE,YAAY,EAmGzC,CAAC"}
@@ -0,0 +1,144 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.sessionCommands = void 0;
37
+ const output_1 = require("../../utils/output");
38
+ const conversations_1 = require("../../utils/conversations");
39
+ const readline = __importStar(require("readline"));
40
+ exports.sessionCommands = [
41
+ {
42
+ name: 'resume',
43
+ description: 'Resume a previous conversation',
44
+ group: 'session',
45
+ handler: async (agent) => {
46
+ const convos = (0, conversations_1.loadConversations)();
47
+ if (convos.length === 0) {
48
+ console.log(output_1.theme.dim(' No previous conversations.'));
49
+ return;
50
+ }
51
+ console.log('');
52
+ console.log(output_1.theme.dim(' Recent conversations:'));
53
+ console.log('');
54
+ const recent = convos.slice(-5).reverse();
55
+ for (let i = 0; i < recent.length; i++) {
56
+ const c = recent[i];
57
+ const ago = getTimeAgo(c.lastActive);
58
+ const selected = i === 0 ? output_1.theme.brand('›') : ' ';
59
+ console.log(` ${selected} ${output_1.theme.white(`${i + 1}. ${c.name}`)} ${output_1.theme.dim(`· ${ago} · ${c.messageCount} msgs`)}`);
60
+ }
61
+ console.log('');
62
+ const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
63
+ const answer = await new Promise(r => {
64
+ rl.question(` ${output_1.theme.dim('select (1-5)?')} ${output_1.theme.brand('›')} `, a => { r(a.trim()); rl.close(); });
65
+ });
66
+ const idx = parseInt(answer, 10) - 1;
67
+ if (idx >= 0 && idx < recent.length) {
68
+ agent.sessions.currentSessionId = recent[idx].id;
69
+ await agent.sessions.loadCheckpoint();
70
+ (0, output_1.printSuccess)(`resumed: ${recent[idx].name}`);
71
+ }
72
+ },
73
+ },
74
+ {
75
+ name: 'rename',
76
+ description: 'Rename current conversation',
77
+ group: 'session',
78
+ handler: async (agent) => {
79
+ const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
80
+ const name = await new Promise(r => {
81
+ rl.question(` ${output_1.theme.dim('new name?')} ${output_1.theme.brand('›')} `, a => { r(a.trim()); rl.close(); });
82
+ });
83
+ if (name) {
84
+ (0, conversations_1.updateConversation)(agent.sessions.currentSessionId, { name });
85
+ (0, output_1.printSuccess)(`renamed to: ${name}`);
86
+ }
87
+ },
88
+ },
89
+ {
90
+ name: 'rewind',
91
+ description: 'Rewind to a previous point',
92
+ group: 'session',
93
+ handler: async (agent) => {
94
+ const msgs = agent.sessions.state.messages;
95
+ const userMsgs = msgs.filter((m) => m.role === 'user');
96
+ if (userMsgs.length < 2) {
97
+ console.log(output_1.theme.dim(' Not enough turns to rewind.'));
98
+ return;
99
+ }
100
+ console.log('');
101
+ console.log(output_1.theme.dim(' Conversation turns:'));
102
+ console.log('');
103
+ for (let i = 0; i < userMsgs.length; i++) {
104
+ const preview = userMsgs[i].content.substring(0, 50);
105
+ console.log(` ${output_1.theme.dim(`${i + 1}.`)} ${output_1.theme.white(`"${preview}${preview.length >= 50 ? '...' : ''}"`)}`);
106
+ }
107
+ console.log('');
108
+ const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
109
+ const answer = await new Promise(r => {
110
+ rl.question(` ${output_1.theme.dim('rewind to turn?')} ${output_1.theme.brand('›')} `, a => { r(a.trim()); rl.close(); });
111
+ });
112
+ const turn = parseInt(answer, 10);
113
+ if (turn > 0 && turn <= userMsgs.length) {
114
+ // Find the index of the nth user message and truncate after it
115
+ let count = 0;
116
+ let cutIdx = 0;
117
+ for (let i = 0; i < msgs.length; i++) {
118
+ if (msgs[i].role === 'user') {
119
+ count++;
120
+ if (count === turn) {
121
+ cutIdx = i + 1;
122
+ break;
123
+ }
124
+ }
125
+ }
126
+ agent.sessions.state.messages = msgs.slice(0, cutIdx);
127
+ await agent.sessions.saveCheckpoint();
128
+ (0, output_1.printSuccess)(`rewound to turn ${turn}`);
129
+ }
130
+ },
131
+ },
132
+ ];
133
+ function getTimeAgo(dateStr) {
134
+ const ms = Date.now() - new Date(dateStr).getTime();
135
+ const mins = Math.floor(ms / 60000);
136
+ if (mins < 60)
137
+ return `${mins}m ago`;
138
+ const hours = Math.floor(mins / 60);
139
+ if (hours < 24)
140
+ return `${hours}h ago`;
141
+ const days = Math.floor(hours / 24);
142
+ return `${days}d ago`;
143
+ }
144
+ //# sourceMappingURL=session.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session.js","sourceRoot":"","sources":["../../../src/commands/slash/session.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AACA,+CAAyD;AACzD,6DAAkF;AAClF,mDAAqC;AAExB,QAAA,eAAe,GAAmB;IAC7C;QACE,IAAI,EAAE,QAAQ;QACd,WAAW,EAAE,gCAAgC;QAC7C,KAAK,EAAE,SAAS;QAChB,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE;YACvB,MAAM,MAAM,GAAG,IAAA,iCAAiB,GAAE,CAAC;YACnC,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACxB,OAAO,CAAC,GAAG,CAAC,cAAK,CAAC,GAAG,CAAC,8BAA8B,CAAC,CAAC,CAAC;gBACvD,OAAO;YACT,CAAC;YAED,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAChB,OAAO,CAAC,GAAG,CAAC,cAAK,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAC,CAAC;YAClD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAEhB,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;YAC1C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBACvC,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;gBACpB,MAAM,GAAG,GAAG,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC;gBACrC,MAAM,QAAQ,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,cAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;gBAClD,OAAO,CAAC,GAAG,CAAC,KAAK,QAAQ,IAAI,cAAK,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC,KAAK,cAAK,CAAC,GAAG,CAAC,KAAK,GAAG,OAAO,CAAC,CAAC,YAAY,OAAO,CAAC,EAAE,CAAC,CAAC;YACzH,CAAC;YACD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAEhB,MAAM,EAAE,GAAG,QAAQ,CAAC,eAAe,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;YACtF,MAAM,MAAM,GAAG,MAAM,IAAI,OAAO,CAAS,CAAC,CAAC,EAAE;gBAC3C,EAAE,CAAC,QAAQ,CAAC,KAAK,cAAK,CAAC,GAAG,CAAC,eAAe,CAAC,IAAI,cAAK,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;YACzG,CAAC,CAAC,CAAC;YAEH,MAAM,GAAG,GAAG,QAAQ,CAAC,MAAM,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC;YACrC,IAAI,GAAG,IAAI,CAAC,IAAI,GAAG,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC;gBACpC,KAAK,CAAC,QAAQ,CAAC,gBAAgB,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;gBACjD,MAAM,KAAK,CAAC,QAAQ,CAAC,cAAc,EAAE,CAAC;gBACtC,IAAA,qBAAY,EAAC,YAAY,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;YAC/C,CAAC;QACH,CAAC;KACF;IACD;QACE,IAAI,EAAE,QAAQ;QACd,WAAW,EAAE,6BAA6B;QAC1C,KAAK,EAAE,SAAS;QAChB,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE;YACvB,MAAM,EAAE,GAAG,QAAQ,CAAC,eAAe,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;YACtF,MAAM,IAAI,GAAG,MAAM,IAAI,OAAO,CAAS,CAAC,CAAC,EAAE;gBACzC,EAAE,CAAC,QAAQ,CAAC,KAAK,cAAK,CAAC,GAAG,CAAC,WAAW,CAAC,IAAI,cAAK,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;YACrG,CAAC,CAAC,CAAC;YAEH,IAAI,IAAI,EAAE,CAAC;gBACT,IAAA,kCAAkB,EAAC,KAAK,CAAC,QAAQ,CAAC,gBAAgB,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;gBAC9D,IAAA,qBAAY,EAAC,eAAe,IAAI,EAAE,CAAC,CAAC;YACtC,CAAC;QACH,CAAC;KACF;IACD;QACE,IAAI,EAAE,QAAQ;QACd,WAAW,EAAE,4BAA4B;QACzC,KAAK,EAAE,SAAS;QAChB,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE;YACvB,MAAM,IAAI,GAAG,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC;YAC3C,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC;YAE5D,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACxB,OAAO,CAAC,GAAG,CAAC,cAAK,CAAC,GAAG,CAAC,+BAA+B,CAAC,CAAC,CAAC;gBACxD,OAAO;YACT,CAAC;YAED,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAChB,OAAO,CAAC,GAAG,CAAC,cAAK,CAAC,GAAG,CAAC,uBAAuB,CAAC,CAAC,CAAC;YAChD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAEhB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,QAAQ,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBACzC,MAAM,OAAO,GAAI,QAAQ,CAAC,CAAC,CAAS,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;gBAC9D,OAAO,CAAC,GAAG,CAAC,OAAO,cAAK,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,cAAK,CAAC,KAAK,CAAC,IAAI,OAAO,GAAG,OAAO,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC;YAClH,CAAC;YACD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAEhB,MAAM,EAAE,GAAG,QAAQ,CAAC,eAAe,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;YACtF,MAAM,MAAM,GAAG,MAAM,IAAI,OAAO,CAAS,CAAC,CAAC,EAAE;gBAC3C,EAAE,CAAC,QAAQ,CAAC,KAAK,cAAK,CAAC,GAAG,CAAC,iBAAiB,CAAC,IAAI,cAAK,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;YAC3G,CAAC,CAAC,CAAC;YAEH,MAAM,IAAI,GAAG,QAAQ,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;YAClC,IAAI,IAAI,GAAG,CAAC,IAAI,IAAI,IAAI,QAAQ,CAAC,MAAM,EAAE,CAAC;gBACxC,+DAA+D;gBAC/D,IAAI,KAAK,GAAG,CAAC,CAAC;gBACd,IAAI,MAAM,GAAG,CAAC,CAAC;gBACf,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;oBACrC,IAAK,IAAI,CAAC,CAAC,CAAS,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;wBACrC,KAAK,EAAE,CAAC;wBACR,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;4BAAC,MAAM,GAAG,CAAC,GAAG,CAAC,CAAC;4BAAC,MAAM;wBAAC,CAAC;oBAChD,CAAC;gBACH,CAAC;gBACD,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,MAAM,CAAQ,CAAC;gBAC7D,MAAM,KAAK,CAAC,QAAQ,CAAC,cAAc,EAAE,CAAC;gBACtC,IAAA,qBAAY,EAAC,mBAAmB,IAAI,EAAE,CAAC,CAAC;YAC1C,CAAC;QACH,CAAC;KACF;CACF,CAAC;AAEF,SAAS,UAAU,CAAC,OAAe;IACjC,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,IAAI,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,CAAC;IACpD,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,GAAG,KAAK,CAAC,CAAC;IACpC,IAAI,IAAI,GAAG,EAAE;QAAE,OAAO,GAAG,IAAI,OAAO,CAAC;IACrC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,EAAE,CAAC,CAAC;IACpC,IAAI,KAAK,GAAG,EAAE;QAAE,OAAO,GAAG,KAAK,OAAO,CAAC;IACvC,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,EAAE,CAAC,CAAC;IACpC,OAAO,GAAG,IAAI,OAAO,CAAC;AACxB,CAAC"}
@@ -36,12 +36,18 @@ export declare class CoWorkerAgent {
36
36
  */
37
37
  chat(prompt: string): AsyncGenerator<string, void, unknown>;
38
38
  /**
39
- * Calls helix-1.2 via Ollama's OpenAI-compatible /v1/chat/completions endpoint.
39
+ * Non-streaming LLM call used to check for tool_calls.
40
40
  */
41
- private callLLM;
41
+ private callLLMFull;
42
+ /**
43
+ * TRUE SSE STREAMING — yields text chunks as they arrive from the network.
44
+ * This is what makes the response feel natural and alive.
45
+ */
46
+ private callLLMStream;
42
47
  /**
43
48
  * Local tool dispatcher. Maps tool names to NativeTools methods.
44
49
  * This is what makes CoWorker actually create files on the user's machine.
50
+ * ALL 35 tools are wired here.
45
51
  */
46
52
  private executeToolLocally;
47
53
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"CoWorkerAgent.d.ts","sourceRoot":"","sources":["../../src/core/CoWorkerAgent.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,sCAAsC,CAAC;AAE7E,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,mBAAmB,EAAE,MAAM,+BAA+B,CAAC;AACpE,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAQ5D,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,SAAS,GAAG,WAAW,GAAG,cAAc,GAAG,YAAY,CAAC;IAC9D,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,iFAAiF;IACjF,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAkED;;;;GAIG;AACH,qBAAa,aAAa;IACjB,KAAK,EAAE,UAAU,CAAC;IAClB,WAAW,EAAE,qBAAqB,CAAC;IACnC,QAAQ,EAAE,cAAc,CAAC;IACzB,GAAG,EAAE,gBAAgB,CAAC;IACtB,KAAK,EAAE,mBAAmB,CAAC;IAC3B,QAAQ,EAAE,eAAe,CAAC;IAEjC,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,GAAG,CAAS;IACpB,OAAO,CAAC,YAAY,CAAkC;gBAE1C,OAAO,EAAE,eAAe;IAcvB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAkBlC;;;OAGG;IACW,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,cAAc,CAAC,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC;IAqGzE;;OAEG;YACW,OAAO;IAoCrB;;;OAGG;YACW,kBAAkB;IA+ChC;;OAEG;IACU,cAAc,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;CAQnF"}
1
+ {"version":3,"file":"CoWorkerAgent.d.ts","sourceRoot":"","sources":["../../src/core/CoWorkerAgent.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,sCAAsC,CAAC;AAE7E,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,mBAAmB,EAAE,MAAM,+BAA+B,CAAC;AACpE,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAQ5D,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,SAAS,GAAG,WAAW,GAAG,cAAc,GAAG,YAAY,CAAC;IAC9D,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,iFAAiF;IACjF,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAmFD;;;;GAIG;AACH,qBAAa,aAAa;IACjB,KAAK,EAAE,UAAU,CAAC;IAClB,WAAW,EAAE,qBAAqB,CAAC;IACnC,QAAQ,EAAE,cAAc,CAAC;IACzB,GAAG,EAAE,gBAAgB,CAAC;IACtB,KAAK,EAAE,mBAAmB,CAAC;IAC3B,QAAQ,EAAE,eAAe,CAAC;IAEjC,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,GAAG,CAAS;IACpB,OAAO,CAAC,YAAY,CAAkC;gBAE1C,OAAO,EAAE,eAAe;IAcvB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAkBlC;;;OAGG;IACW,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,cAAc,CAAC,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC;IAyGzE;;OAEG;YACW,WAAW;IA+BzB;;;OAGG;YACY,aAAa;IAoE5B;;;;OAIG;YACW,kBAAkB;IA+GhC;;OAEG;IACU,cAAc,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;CAQnF"}
@@ -89,7 +89,11 @@ async function getSystemPrompt(cwd) {
89
89
  let promptText = FALLBACK_SYSTEM_PROMPT;
90
90
  try {
91
91
  promptText = fs.readFileSync(promptPath, 'utf8');
92
- promptText = promptText.replace(/Claude Code/g, 'CoWorker');
92
+ // Global branding override — catch all variants
93
+ promptText = promptText
94
+ .replace(/Claude Code/gi, 'CoWorker')
95
+ .replace(/Claude/gi, 'CoWorker')
96
+ .replace(/Anthropic/gi, 'Sylix');
93
97
  }
94
98
  catch (err) {
95
99
  return FALLBACK_SYSTEM_PROMPT;
@@ -106,7 +110,20 @@ async function getSystemPrompt(cwd) {
106
110
  .replace(/Current branch: [^\n]+/, `Current branch: ${gitContext.branch}`)
107
111
  .replace(/\(clean\)/, gitContext.status)
108
112
  .replace('${Last 5 Recent commits}', gitContext.commits);
109
- return promptText;
113
+ // Project memory support (.coworker.md / COWORKER.md)
114
+ let projectMemory = '';
115
+ const memoryFiles = ['.coworker.md', 'COWORKER.md'];
116
+ for (const file of memoryFiles) {
117
+ const memPath = path.join(cwd, file);
118
+ if (fs.existsSync(memPath)) {
119
+ try {
120
+ projectMemory = `\n\nPROJECT CONTEXT (from ${file}):\n${fs.readFileSync(memPath, 'utf8')}`;
121
+ break;
122
+ }
123
+ catch { }
124
+ }
125
+ }
126
+ return promptText + projectMemory;
110
127
  }
111
128
  /**
112
129
  * THE SDK LAYER — Real Agentic Tool Loop.
@@ -147,29 +164,30 @@ class CoWorkerAgent {
147
164
  */
148
165
  async *chat(prompt) {
149
166
  await this.sessions.rollupMemory();
150
- // Build conversation history from session
151
167
  const messages = [
152
168
  { role: 'system', content: this.systemPrompt },
153
169
  ...this.sessions.state.messages
154
170
  ];
155
- // Add new user prompt
156
171
  const userMsg = { role: 'user', content: prompt };
157
172
  messages.push(userMsg);
158
173
  await this.sessions.appendMessage(userMsg);
159
174
  let turnCount = 0;
160
175
  while (turnCount < MAX_TOOL_TURNS) {
161
176
  turnCount++;
162
- // Call the LLM
163
- const response = await this.callLLM(messages);
164
- // If the LLM produced text content, yield it
165
- if (response.content) {
166
- yield response.content;
167
- }
168
- // If no tool_calls, we're done
177
+ // First, try a non-streaming call to check for tool_calls
178
+ const response = await this.callLLMFull(messages);
179
+ // If no tool_calls, this is the final response stream it
169
180
  if (!response.tool_calls || response.tool_calls.length === 0) {
181
+ if (response.content) {
182
+ // Re-request with streaming enabled for the final response
183
+ yield* this.callLLMStream(messages);
184
+ }
170
185
  break;
171
186
  }
172
- // Add the assistant message with tool_calls to history
187
+ // Has tool calls yield any content prefix, then execute tools
188
+ if (response.content) {
189
+ yield response.content;
190
+ }
173
191
  const assistantMsg = {
174
192
  role: 'assistant',
175
193
  content: response.content || '',
@@ -177,7 +195,6 @@ class CoWorkerAgent {
177
195
  };
178
196
  messages.push(assistantMsg);
179
197
  await this.sessions.appendMessage(assistantMsg);
180
- // Execute each tool call locally
181
198
  for (const tc of response.tool_calls) {
182
199
  const toolName = tc.function?.name;
183
200
  const toolId = tc.id || `call_${(0, crypto_1.randomUUID)().substring(0, 8)}`;
@@ -191,7 +208,6 @@ class CoWorkerAgent {
191
208
  yield `\n⚠️ ${errMsg}\n`;
192
209
  continue;
193
210
  }
194
- // Permission check for mutation tools
195
211
  const mutationTools = ['executeWrite', 'run_terminal_command', 'executeBash'];
196
212
  if (mutationTools.includes(toolName)) {
197
213
  const allowed = await this.permissions.intercept(toolName, args);
@@ -202,9 +218,7 @@ class CoWorkerAgent {
202
218
  continue;
203
219
  }
204
220
  }
205
- // Pre-tool hook
206
221
  await this.hooks.firePreToolHook(toolName, args);
207
- // Execute the tool
208
222
  yield `\n🔧 Executing: ${toolName}...\n`;
209
223
  let result;
210
224
  try {
@@ -213,26 +227,33 @@ class CoWorkerAgent {
213
227
  catch (e) {
214
228
  result = `[ToolError] ${toolName} crashed: ${e.message}`;
215
229
  }
216
- // Post-tool hook
217
- await this.hooks.firePostToolHook(toolName, result);
218
- // Feed result back to LLM
230
+ await this.hooks.firePostToolHook(toolName, result, args);
219
231
  const toolMsg = { role: 'tool', content: result, tool_call_id: toolId };
220
232
  messages.push(toolMsg);
221
233
  await this.sessions.appendMessage(toolMsg);
222
- // Show truncated result to user
234
+ // Inline error detection
235
+ if (this.hooks.lastDiagnostic?.hasErrors) {
236
+ const diag = this.hooks.lastDiagnostic;
237
+ const errorMsg = {
238
+ role: 'system',
239
+ content: `[DIAGNOSTICS] After your ${toolName} on ${diag.filePath}, errors detected by ${diag.tool}:\n${diag.errors}\n\nYou MUST fix these errors before proceeding.`
240
+ };
241
+ messages.push(errorMsg);
242
+ await this.sessions.appendMessage(errorMsg);
243
+ yield `\n⚠️ [${diag.tool}] Detected errors — agent will self-correct...\n`;
244
+ }
223
245
  const preview = result.length > 200 ? result.substring(0, 200) + '...' : result;
224
246
  yield ` ✅ ${preview}\n`;
225
247
  }
226
- // Loop back — the LLM will see the tool results and decide what to do next
227
248
  }
228
249
  if (turnCount >= MAX_TOOL_TURNS) {
229
250
  yield `\n⚠️ Reached maximum tool turns (${MAX_TOOL_TURNS}). Stopping.\n`;
230
251
  }
231
252
  }
232
253
  /**
233
- * Calls helix-1.2 via Ollama's OpenAI-compatible /v1/chat/completions endpoint.
254
+ * Non-streaming LLM call used to check for tool_calls.
234
255
  */
235
- async callLLM(messages) {
256
+ async callLLMFull(messages) {
236
257
  const url = `${this.endpoint}/v1/chat/completions`;
237
258
  const body = {
238
259
  model: this.ollamaModel,
@@ -240,11 +261,7 @@ class CoWorkerAgent {
240
261
  tools: Schemas_1.CoWorkerToolSchemas,
241
262
  tool_choice: 'auto',
242
263
  stream: false,
243
- options: {
244
- num_ctx: 32768,
245
- num_predict: 4096,
246
- temperature: 0.7
247
- }
264
+ options: { num_ctx: 32768, num_predict: 4096, temperature: 0.7 }
248
265
  };
249
266
  const res = await (0, node_fetch_1.default)(url, {
250
267
  method: 'POST',
@@ -262,32 +279,133 @@ class CoWorkerAgent {
262
279
  tool_calls: message.tool_calls || []
263
280
  };
264
281
  }
282
+ /**
283
+ * TRUE SSE STREAMING — yields text chunks as they arrive from the network.
284
+ * This is what makes the response feel natural and alive.
285
+ */
286
+ async *callLLMStream(messages) {
287
+ const url = `${this.endpoint}/v1/chat/completions`;
288
+ const body = {
289
+ model: this.ollamaModel,
290
+ messages,
291
+ tools: Schemas_1.CoWorkerToolSchemas,
292
+ tool_choice: 'auto',
293
+ stream: true,
294
+ options: { num_ctx: 32768, num_predict: 4096, temperature: 0.7 }
295
+ };
296
+ const res = await (0, node_fetch_1.default)(url, {
297
+ method: 'POST',
298
+ headers: { 'Content-Type': 'application/json' },
299
+ body: JSON.stringify(body)
300
+ });
301
+ if (!res.ok) {
302
+ const errText = await res.text();
303
+ throw new Error(`LLM call failed (${res.status}): ${errText}`);
304
+ }
305
+ const nodeStream = res.body;
306
+ if (!nodeStream)
307
+ throw new Error('No response body');
308
+ let buffer = '';
309
+ let fullContent = '';
310
+ // Read the SSE stream chunk by chunk
311
+ for await (const rawChunk of nodeStream) {
312
+ buffer += rawChunk.toString();
313
+ // Process complete SSE lines
314
+ const lines = buffer.split('\n');
315
+ buffer = lines.pop() || ''; // Keep incomplete last line in buffer
316
+ for (const line of lines) {
317
+ const trimmed = line.trim();
318
+ if (!trimmed || !trimmed.startsWith('data: '))
319
+ continue;
320
+ const data = trimmed.slice(6).trim();
321
+ if (data === '[DONE]')
322
+ return;
323
+ try {
324
+ const parsed = JSON.parse(data);
325
+ const content = parsed.choices?.[0]?.delta?.content ||
326
+ parsed.message?.content ||
327
+ parsed.response ||
328
+ '';
329
+ if (content) {
330
+ fullContent += content;
331
+ yield content; // Yield IMMEDIATELY — no buffering
332
+ }
333
+ }
334
+ catch {
335
+ // Partial JSON or non-JSON line — skip
336
+ }
337
+ }
338
+ }
339
+ // Save the full response to session
340
+ if (fullContent) {
341
+ await this.sessions.appendMessage({ role: 'assistant', content: fullContent });
342
+ }
343
+ }
265
344
  /**
266
345
  * Local tool dispatcher. Maps tool names to NativeTools methods.
267
346
  * This is what makes CoWorker actually create files on the user's machine.
347
+ * ALL 35 tools are wired here.
268
348
  */
269
349
  async executeToolLocally(toolName, args) {
270
350
  switch (toolName) {
271
- case 'executeOpenBrowser':
272
- return NativeTools_1.NativeTools.executeOpenBrowser(args.url);
351
+ // ── Filesystem ──
273
352
  case 'executeRead':
274
353
  return NativeTools_1.NativeTools.executeRead(args.filePath);
275
- case 'executeListDir':
276
- return NativeTools_1.NativeTools.executeListDir(args.dirPath);
277
- case 'executeBash':
278
- return NativeTools_1.NativeTools.executeBash(args.command, args.cwd);
279
354
  case 'executeWrite':
280
355
  return NativeTools_1.NativeTools.executeWrite(args.filePath, args.content);
356
+ case 'executeEdit':
357
+ return NativeTools_1.NativeTools.executeEdit(args.filePath, args.oldString, args.newString, args.replaceAll);
358
+ case 'executeMultiEdit':
359
+ return NativeTools_1.NativeTools.executeMultiEdit(args.filePath, args.edits);
360
+ case 'executeLS':
361
+ return NativeTools_1.NativeTools.executeLS(args.path, args.recursive);
362
+ case 'executeListDir':
363
+ return NativeTools_1.NativeTools.executeListDir(args.dirPath);
281
364
  case 'executeGlob':
282
365
  return (await NativeTools_1.NativeTools.executeGlob(args.pattern, args.dir)).join('\n');
283
366
  case 'executeGrep':
284
367
  return NativeTools_1.NativeTools.executeGrep(args.regexQuery, args.filesToSearch);
368
+ // ── Diagnostics (inline error detection) ──
369
+ case 'diagnostics':
370
+ return this.hooks.runManualDiagnostics(args.filePath);
371
+ // ── Code Review ──
372
+ case 'codeReview': {
373
+ const { CodeReviewEngine } = await Promise.resolve().then(() => __importStar(require('../review/CodeReviewEngine')));
374
+ const engine = new CodeReviewEngine();
375
+ const result = await engine.review(args.baseBranch);
376
+ return CodeReviewEngine.formatForTerminal(result);
377
+ }
378
+ // ── Shell & Process ──
379
+ case 'executeBash':
380
+ return NativeTools_1.NativeTools.executeBash(args.command, args.cwd);
381
+ case 'bashOutput':
382
+ return NativeTools_1.NativeTools.executeBashOutput(args.pid);
383
+ case 'killShell':
384
+ return NativeTools_1.NativeTools.executeKillShell(args.pid);
385
+ // ── Git ──
386
+ case 'gitStatus':
387
+ return NativeTools_1.NativeTools.executeGitStatus(args.cwd);
388
+ case 'gitDiff':
389
+ return NativeTools_1.NativeTools.executeGitDiff(args.filePath, args.staged, args.cwd);
390
+ case 'gitCommit':
391
+ return NativeTools_1.NativeTools.executeGitCommit(args.message, args.files, args.cwd);
392
+ // ── Memory (COWORKER.md) ──
393
+ case 'memoryRead':
394
+ return NativeTools_1.NativeTools.executeMemoryRead();
395
+ case 'memoryWrite':
396
+ return NativeTools_1.NativeTools.executeMemoryWrite(args.content, args.mode);
397
+ // ── Web ──
285
398
  case 'executeWebSearch':
286
399
  return NativeTools_1.NativeTools.executeWebSearch(args.query);
287
400
  case 'executeWebFetch':
288
401
  return NativeTools_1.NativeTools.executeWebFetch(args.url);
289
- case 'executeAskUserQuestion':
290
- return NativeTools_1.NativeTools.executeAskUserQuestion(args.question);
402
+ case 'executeOpenBrowser':
403
+ return NativeTools_1.NativeTools.executeOpenBrowser(args.url);
404
+ // ── Task Management ──
405
+ case 'todoRead':
406
+ return NativeTools_1.NativeTools.executeTodoRead();
407
+ case 'todoWrite':
408
+ return NativeTools_1.NativeTools.executeTodoWrite(args.todos);
291
409
  case 'taskCreate': {
292
410
  const id = await this.tasks.createTask(args.description, args.dependencies || []);
293
411
  return `Task created with ID: ${id}`;
@@ -296,6 +414,31 @@ class CoWorkerAgent {
296
414
  await this.tasks.updateTaskState(args.taskId, args.state, args.notes);
297
415
  return `Task ${args.taskId} updated to ${args.state}`;
298
416
  }
417
+ // ── Interaction ──
418
+ case 'executeAskUserQuestion':
419
+ return NativeTools_1.NativeTools.executeAskUserQuestion(args.question);
420
+ // ── Jupyter Notebooks ──
421
+ case 'executeNotebookRead':
422
+ return NativeTools_1.NativeTools.executeNotebookRead(args.notebookPath);
423
+ case 'executeNotebookEdit':
424
+ return NativeTools_1.NativeTools.executeNotebookEdit(args.notebookPath, args.newSource, args.cellId, args.cellType);
425
+ // ── Agents ──
426
+ case 'agent':
427
+ return NativeTools_1.NativeTools.executeAgent(args.description, args.subagentType);
428
+ case 'returnSubagentResult':
429
+ return NativeTools_1.NativeTools.executeReturnSubagentResult(args.result);
430
+ // ── Plan Mode (handled by permission interceptor state) ──
431
+ case 'enterPlanMode':
432
+ return 'Plan mode activated. Mutation tools (bash, write, edit) are now blocked until you call exitPlanMode.';
433
+ case 'exitPlanMode':
434
+ return 'Plan mode deactivated. Mutation tools are re-enabled.';
435
+ // ── Cron (stub — uses executeBash internally) ──
436
+ case 'cronCreate':
437
+ return `Cron scheduled: "${args.description}" every ${args.intervalMinutes} minutes. (Note: cron runs in-process only while CoWorker is active.)`;
438
+ case 'cronList':
439
+ return 'No active crons. (Cron persistence is not yet implemented.)';
440
+ case 'cronDelete':
441
+ return `Cron ${args.cronId} deleted.`;
299
442
  default:
300
443
  return `[Unknown Tool] "${toolName}" is not registered in CoWorker's local executor.`;
301
444
  }