spidersan 0.2.5 → 0.3.3

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 (101) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/README.md +14 -33
  3. package/dist/bin/spidersan.d.ts.map +1 -1
  4. package/dist/bin/spidersan.js +12 -4
  5. package/dist/bin/spidersan.js.map +1 -1
  6. package/dist/commands/collab-sync.d.ts.map +1 -1
  7. package/dist/commands/collab-sync.js +44 -20
  8. package/dist/commands/collab-sync.js.map +1 -1
  9. package/dist/commands/conflicts.js.map +1 -1
  10. package/dist/commands/demo.d.ts.map +1 -1
  11. package/dist/commands/demo.js +24 -19
  12. package/dist/commands/demo.js.map +1 -1
  13. package/dist/commands/doctor.d.ts.map +1 -1
  14. package/dist/commands/doctor.js +40 -0
  15. package/dist/commands/doctor.js.map +1 -1
  16. package/dist/commands/inbox.d.ts.map +1 -1
  17. package/dist/commands/inbox.js +81 -27
  18. package/dist/commands/inbox.js.map +1 -1
  19. package/dist/commands/index.d.ts +5 -0
  20. package/dist/commands/index.d.ts.map +1 -1
  21. package/dist/commands/index.js +7 -0
  22. package/dist/commands/index.js.map +1 -1
  23. package/dist/commands/lock.d.ts.map +1 -1
  24. package/dist/commands/lock.js +47 -10
  25. package/dist/commands/lock.js.map +1 -1
  26. package/dist/commands/monitor.d.ts +3 -0
  27. package/dist/commands/monitor.d.ts.map +1 -0
  28. package/dist/commands/monitor.js +153 -0
  29. package/dist/commands/monitor.js.map +1 -0
  30. package/dist/commands/msg-read.d.ts.map +1 -1
  31. package/dist/commands/msg-read.js +59 -34
  32. package/dist/commands/msg-read.js.map +1 -1
  33. package/dist/commands/rescue.d.ts +11 -0
  34. package/dist/commands/rescue.d.ts.map +1 -0
  35. package/dist/commands/rescue.js +90 -0
  36. package/dist/commands/rescue.js.map +1 -0
  37. package/dist/commands/semantic.d.ts +3 -0
  38. package/dist/commands/semantic.d.ts.map +1 -0
  39. package/dist/commands/semantic.js +62 -0
  40. package/dist/commands/semantic.js.map +1 -0
  41. package/dist/commands/send.d.ts.map +1 -1
  42. package/dist/commands/send.js +53 -66
  43. package/dist/commands/send.js.map +1 -1
  44. package/dist/commands/stale.d.ts +1 -0
  45. package/dist/commands/stale.d.ts.map +1 -1
  46. package/dist/commands/stale.js +101 -1
  47. package/dist/commands/stale.js.map +1 -1
  48. package/dist/commands/tension.d.ts.map +1 -1
  49. package/dist/commands/tension.js +27 -7
  50. package/dist/commands/tension.js.map +1 -1
  51. package/dist/commands/torrent.d.ts.map +1 -1
  52. package/dist/commands/torrent.js +23 -18
  53. package/dist/commands/torrent.js.map +1 -1
  54. package/dist/commands/welcome.d.ts +3 -0
  55. package/dist/commands/welcome.d.ts.map +1 -0
  56. package/dist/commands/welcome.js +92 -0
  57. package/dist/commands/welcome.js.map +1 -0
  58. package/dist/commands/who-owns.d.ts +3 -0
  59. package/dist/commands/who-owns.d.ts.map +1 -0
  60. package/dist/commands/who-owns.js +68 -0
  61. package/dist/commands/who-owns.js.map +1 -0
  62. package/dist/commands/who-touched.d.ts.map +1 -1
  63. package/dist/commands/who-touched.js +22 -10
  64. package/dist/commands/who-touched.js.map +1 -1
  65. package/dist/lib/ast.d.ts +20 -40
  66. package/dist/lib/ast.d.ts.map +1 -1
  67. package/dist/lib/ast.js +55 -101
  68. package/dist/lib/ast.js.map +1 -1
  69. package/dist/lib/license.d.ts +0 -1
  70. package/dist/lib/license.d.ts.map +1 -1
  71. package/dist/lib/license.js +2 -5
  72. package/dist/lib/license.js.map +1 -1
  73. package/dist/storage/git-messages.d.ts +53 -0
  74. package/dist/storage/git-messages.d.ts.map +1 -0
  75. package/dist/storage/git-messages.js +372 -0
  76. package/dist/storage/git-messages.js.map +1 -0
  77. package/dist/storage/index.d.ts +5 -0
  78. package/dist/storage/index.d.ts.map +1 -1
  79. package/dist/storage/index.js +7 -0
  80. package/dist/storage/index.js.map +1 -1
  81. package/dist/storage/local-messages.d.ts +37 -0
  82. package/dist/storage/local-messages.d.ts.map +1 -0
  83. package/dist/storage/local-messages.js +151 -0
  84. package/dist/storage/local-messages.js.map +1 -0
  85. package/dist/storage/message-adapter.d.ts +86 -0
  86. package/dist/storage/message-adapter.d.ts.map +1 -0
  87. package/dist/storage/message-adapter.js +28 -0
  88. package/dist/storage/message-adapter.js.map +1 -0
  89. package/dist/storage/message-factory.d.ts +36 -0
  90. package/dist/storage/message-factory.d.ts.map +1 -0
  91. package/dist/storage/message-factory.js +99 -0
  92. package/dist/storage/message-factory.js.map +1 -0
  93. package/dist/storage/mycmail-adapter.d.ts +38 -0
  94. package/dist/storage/mycmail-adapter.d.ts.map +1 -0
  95. package/dist/storage/mycmail-adapter.js +297 -0
  96. package/dist/storage/mycmail-adapter.js.map +1 -0
  97. package/dist/tui/dashboard.d.ts +35 -0
  98. package/dist/tui/dashboard.d.ts.map +1 -0
  99. package/dist/tui/dashboard.js +190 -0
  100. package/dist/tui/dashboard.js.map +1 -0
  101. package/package.json +4 -4
@@ -1,5 +1,6 @@
1
1
  import { Command } from 'commander';
2
- import { execSync, spawnSync } from 'child_process';
2
+ import { execSync } from 'child_process';
3
+ import { getMessageStorage, parseTierOption } from '../storage/message-factory.js';
3
4
  // Security: Input validation
4
5
  const VALID_AGENT_ID = /^[a-z0-9][a-z0-9_-]{0,30}$/i;
5
6
  function validateAgentId(agentId) {
@@ -8,10 +9,6 @@ function validateAgentId(agentId) {
8
9
  }
9
10
  return agentId;
10
11
  }
11
- function sanitizeText(text) {
12
- // Remove shell metacharacters but allow normal text
13
- return text.replace(/[`$(){}[\]|;&<>]/g, '');
14
- }
15
12
  function getMessageFromStdin() {
16
13
  return new Promise((resolve, reject) => {
17
14
  const chunks = [];
@@ -29,7 +26,7 @@ function getCurrentBranch() {
29
26
  }
30
27
  }
31
28
  export const sendCommand = new Command('send')
32
- .description('Send a message to another agent (via Myceliumail)')
29
+ .description('Send a message to another agent (tiered fallback)')
33
30
  .argument('<to>', 'Recipient agent identifier')
34
31
  .argument('<subject>', 'Message subject')
35
32
  .option('-m, --message <text>', 'Message body (or reads from stdin)')
@@ -37,11 +34,21 @@ export const sendCommand = new Command('send')
37
34
  .option('-f, --from <agent>', 'Sender identifier (default: current agent)')
38
35
  .option('-b, --branch <name>', 'Related branch name')
39
36
  .option('--files <files>', 'Comma-separated list of related files')
40
- .option('--reply-to <id>', 'Message ID this is replying to (not yet supported in mycmail)')
41
- .option('--encrypt', 'Encrypt the message')
37
+ .option('--reply-to <id>', 'Message ID this is replying to')
38
+ .option('--encrypt', 'Encrypt the message (Tier 1 only)')
39
+ .option('--tier <n>', 'Force specific tier (1, 2, or 3)')
40
+ .option('-v, --verbose', 'Show which tier is being used')
42
41
  .option('--json', 'Output as JSON')
43
42
  .action(async (to, subject, options) => {
44
- // 1. Get message body
43
+ // 1. Validate recipient
44
+ try {
45
+ validateAgentId(to);
46
+ }
47
+ catch (error) {
48
+ console.error(`❌ ${error.message}`);
49
+ process.exit(1);
50
+ }
51
+ // 2. Get message body
45
52
  let messageBody = options.message;
46
53
  if (!messageBody) {
47
54
  if (process.stdin.isTTY) {
@@ -54,79 +61,59 @@ export const sendCommand = new Command('send')
54
61
  console.error('❌ Message body empty');
55
62
  process.exit(1);
56
63
  }
57
- // 2. Prepare context
64
+ // 3. Prepare context
58
65
  const branch = options.branch || getCurrentBranch();
59
66
  const type = options.type || 'info';
60
67
  const files = options.files ? options.files.split(',') : [];
61
- // 3. Format message with Spidersan context (until mycmail supports metadata)
62
- let contextHeader = '';
63
- if (type !== 'info')
64
- contextHeader += `Type: ${type}\n`;
65
- if (branch)
66
- contextHeader += `Branch: ${branch}\n`;
67
- if (files.length > 0)
68
- contextHeader += `Files: ${files.join(', ')}\n`;
69
- const fullMessage = contextHeader ? `${contextHeader}\n${messageBody}` : messageBody;
70
- // 4. Construct mycmail command
71
- // Note: We use the sender identity for MYCELIUMAIL_AGENT_ID env var
72
68
  const sender = options.from || process.env.SPIDERSAN_AGENT || 'cli-agent';
69
+ // 4. Get message storage adapter
70
+ const forceTier = parseTierOption(options.tier);
73
71
  try {
74
- // Check if mycmail is available
75
- execSync('which mycmail', { stdio: 'ignore' });
76
- }
77
- catch {
78
- console.error('❌ Myceliumail (mycmail) not found.');
79
- console.error(' Please install it: npm install -g myceliumail');
80
- process.exit(1);
81
- }
82
- const cmdParts = [
83
- `MYCELIUMAIL_AGENT_ID=${sender}`,
84
- 'mycmail',
85
- 'send',
86
- to,
87
- `"${subject}"`, // Subject needs quotes
88
- '--message',
89
- `"${fullMessage.replace(/"/g, '\\"')}"` // Escape quotes in message
90
- ];
91
- if (options.encrypt) {
92
- cmdParts.push('--encrypt');
93
- }
94
- // Execute
95
- // Execute using execFileSync with argument array (prevents shell injection)
96
- try {
97
- // Security: Validate and sanitize inputs
98
- const safeTo = validateAgentId(to);
99
- const safeSubject = sanitizeText(subject);
100
- const safeMessage = sanitizeText(fullMessage);
101
- const args = ['send', safeTo, safeSubject, '--message', safeMessage];
102
- if (options.encrypt) {
103
- args.push('--encrypt');
104
- }
105
- const result = spawnSync('mycmail', args, {
106
- encoding: 'utf-8',
107
- env: { ...process.env, MYCELIUMAIL_AGENT_ID: sender }
72
+ const storage = await getMessageStorage({
73
+ forceTier,
74
+ agentId: sender,
75
+ verbose: options.verbose,
108
76
  });
109
- if (result.error) {
110
- throw result.error;
77
+ // Warn if encryption requested but not on Tier 1
78
+ if (options.encrypt && storage.getTier() !== 1) {
79
+ console.error('⚠️ Encryption only supported on Tier 1 (mycmail). Message will be sent unencrypted.');
111
80
  }
112
- const output = result.stdout || '';
81
+ // 5. Send message
82
+ const message = await storage.send({
83
+ from: sender,
84
+ to,
85
+ subject,
86
+ body: messageBody,
87
+ type,
88
+ encrypted: options.encrypt && storage.getTier() === 1,
89
+ branch: branch || undefined,
90
+ files: files.length > 0 ? files : undefined,
91
+ });
113
92
  if (options.json) {
114
- // Try to parse mycmail output or create synthetic JSON
115
- // mycmail 1.0.0 output is text. 1.1.0 might have --json
116
93
  console.log(JSON.stringify({
117
94
  status: 'sent',
118
- to,
119
- subject,
120
- encrypted: !!options.encrypt,
121
- original_output: output.trim()
95
+ tier: storage.getTier(),
96
+ tierName: storage.getTierName(),
97
+ message: {
98
+ id: message.id,
99
+ to: message.to,
100
+ subject: message.subject,
101
+ encrypted: message.encrypted,
102
+ timestamp: message.timestamp.toISOString(),
103
+ },
122
104
  }, null, 2));
123
105
  }
124
106
  else {
125
- console.log(output);
107
+ const tierInfo = options.verbose ? ` via ${storage.getTierName()}` : '';
108
+ console.log(`✅ Message sent to ${to}${tierInfo}`);
109
+ if (options.verbose) {
110
+ console.log(` ID: ${message.id}`);
111
+ console.log(` Subject: ${subject}`);
112
+ }
126
113
  }
127
114
  }
128
115
  catch (error) {
129
- console.error('❌ Failed to send message via Myceliumail');
116
+ console.error('❌ Failed to send message');
130
117
  console.error(error.message || error);
131
118
  process.exit(1);
132
119
  }
@@ -1 +1 @@
1
- {"version":3,"file":"send.js","sourceRoot":"","sources":["../../src/commands/send.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"send.js","sourceRoot":"","sources":["../../src/commands/send.ts"],"names":[],"mappings":"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"}
@@ -2,6 +2,7 @@
2
2
  * spidersan stale
3
3
  *
4
4
  * Show branches that haven't been updated recently.
5
+ * With --notify flag: sends notifications to branch owners via mycmail and .pending_task.md updates.
5
6
  */
6
7
  import { Command } from 'commander';
7
8
  export declare const staleCommand: Command;
@@ -1 +1 @@
1
- {"version":3,"file":"stale.d.ts","sourceRoot":"","sources":["../../src/commands/stale.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIpC,eAAO,MAAM,YAAY,SAqCnB,CAAC"}
1
+ {"version":3,"file":"stale.d.ts","sourceRoot":"","sources":["../../src/commands/stale.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAyEpC,eAAO,MAAM,YAAY,SAiFnB,CAAC"}
@@ -2,12 +2,76 @@
2
2
  * spidersan stale
3
3
  *
4
4
  * Show branches that haven't been updated recently.
5
+ * With --notify flag: sends notifications to branch owners via mycmail and .pending_task.md updates.
5
6
  */
6
7
  import { Command } from 'commander';
7
8
  import { getStorage } from '../storage/index.js';
9
+ import { spawnSync } from 'child_process';
10
+ import { existsSync, readFileSync, appendFileSync } from 'fs';
11
+ import { resolve } from 'path';
12
+ /**
13
+ * Send notification to agent via mycmail
14
+ */
15
+ function notifyAgentViaMycmail(agentId, branchName, daysOld) {
16
+ try {
17
+ const subject = `⚠️ Stale branch: ${branchName}`;
18
+ const message = `Your branch "${branchName}" has been inactive for ${daysOld} days.\n\nActions:\n- Run: spidersan cleanup\n- Or resume work and push updates`;
19
+ const result = spawnSync('mycmail', [
20
+ 'send',
21
+ agentId,
22
+ subject,
23
+ '--message',
24
+ message
25
+ ], {
26
+ encoding: 'utf-8',
27
+ env: { ...process.env, MYCELIUMAIL_AGENT_ID: 'spidersan' }
28
+ });
29
+ return result.status === 0;
30
+ }
31
+ catch {
32
+ return false;
33
+ }
34
+ }
35
+ /**
36
+ * Update agent's .pending_task.md file
37
+ */
38
+ function updatePendingTaskFile(agentId, branchName, daysOld) {
39
+ try {
40
+ // Try common locations for .pending_task.md
41
+ const possiblePaths = [
42
+ resolve(process.cwd(), '.pending_task.md'),
43
+ resolve(process.cwd(), `../${agentId}/.pending_task.md`),
44
+ resolve(process.env.HOME || '~', `Dev/${agentId}/.pending_task.md`),
45
+ resolve(process.env.HOME || '~', 'Dev/treebird-internal/.pending_task.md')
46
+ ];
47
+ let taskFilePath = null;
48
+ for (const path of possiblePaths) {
49
+ if (existsSync(path)) {
50
+ taskFilePath = path;
51
+ break;
52
+ }
53
+ }
54
+ if (!taskFilePath) {
55
+ return false;
56
+ }
57
+ const entry = `- [ ] 🕷️ Stale branch: \`${branchName}\` (${daysOld}d inactive) - run \`spidersan cleanup\`\n`;
58
+ // Read file and check if entry already exists
59
+ const content = readFileSync(taskFilePath, 'utf-8');
60
+ if (content.includes(branchName)) {
61
+ return true; // Already notified
62
+ }
63
+ // Append to the file
64
+ appendFileSync(taskFilePath, entry, 'utf-8');
65
+ return true;
66
+ }
67
+ catch {
68
+ return false;
69
+ }
70
+ }
8
71
  export const staleCommand = new Command('stale')
9
72
  .description('Show stale branches (not updated recently)')
10
73
  .option('--days <n>', 'Days threshold for staleness', '7')
74
+ .option('--notify', 'Send notifications to branch owners')
11
75
  .option('--json', 'Output as JSON')
12
76
  .action(async (options) => {
13
77
  const storage = await getStorage();
@@ -20,6 +84,17 @@ export const staleCommand = new Command('stale')
20
84
  threshold.setDate(threshold.getDate() - days);
21
85
  const branches = await storage.list();
22
86
  const stale = branches.filter(b => new Date(b.registeredAt) < threshold);
87
+ // Group by agent if notifying
88
+ const byAgent = new Map();
89
+ if (options.notify) {
90
+ for (const branch of stale) {
91
+ const agent = branch.agent || 'unknown';
92
+ if (!byAgent.has(agent)) {
93
+ byAgent.set(agent, []);
94
+ }
95
+ byAgent.get(agent).push(branch);
96
+ }
97
+ }
23
98
  if (options.json) {
24
99
  console.log(JSON.stringify(stale, null, 2));
25
100
  return;
@@ -31,7 +106,32 @@ export const staleCommand = new Command('stale')
31
106
  console.log(`🕷️ Stale Branches (>${days} days old):\n`);
32
107
  for (const branch of stale) {
33
108
  const age = Math.floor((Date.now() - new Date(branch.registeredAt).getTime()) / 86400000);
34
- console.log(` ⚠️ ${branch.name} (${age} days old)`);
109
+ const agentTag = branch.agent ? ` [@${branch.agent}]` : '';
110
+ console.log(` ⚠️ ${branch.name}${agentTag} (${age} days old)`);
111
+ }
112
+ // Send notifications if requested
113
+ if (options.notify) {
114
+ console.log(`\n📨 Sending notifications...`);
115
+ let mycmailSuccess = 0;
116
+ let fileSuccess = 0;
117
+ for (const [agent, branches] of byAgent) {
118
+ if (agent === 'unknown')
119
+ continue;
120
+ for (const branch of branches) {
121
+ const age = Math.floor((Date.now() - new Date(branch.registeredAt).getTime()) / 86400000);
122
+ // Try mycmail notification
123
+ if (notifyAgentViaMycmail(agent, branch.name, age)) {
124
+ mycmailSuccess++;
125
+ }
126
+ // Try .pending_task.md update
127
+ if (updatePendingTaskFile(agent, branch.name, age)) {
128
+ fileSuccess++;
129
+ }
130
+ }
131
+ }
132
+ console.log(`✅ Notifications sent:`);
133
+ console.log(` - Mycmail: ${mycmailSuccess}/${stale.length}`);
134
+ console.log(` - File updates: ${fileSuccess}/${stale.length}`);
35
135
  }
36
136
  console.log(`\nRun 'spidersan cleanup' to remove these.`);
37
137
  });
@@ -1 +1 @@
1
- {"version":3,"file":"stale.js","sourceRoot":"","sources":["../../src/commands/stale.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAGjD,MAAM,CAAC,MAAM,YAAY,GAAG,IAAI,OAAO,CAAC,OAAO,CAAC;KAC3C,WAAW,CAAC,4CAA4C,CAAC;KACzD,MAAM,CAAC,YAAY,EAAE,8BAA8B,EAAE,GAAG,CAAC;KACzD,MAAM,CAAC,QAAQ,EAAE,gBAAgB,CAAC;KAClC,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE;IACtB,MAAM,OAAO,GAAG,MAAM,UAAU,EAAE,CAAC;IAEnC,IAAI,CAAC,MAAM,OAAO,CAAC,aAAa,EAAE,EAAE,CAAC;QACjC,OAAO,CAAC,KAAK,CAAC,kDAAkD,CAAC,CAAC;QAClE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACpB,CAAC;IAED,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;IACxC,MAAM,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC;IAC7B,SAAS,CAAC,OAAO,CAAC,SAAS,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,CAAC;IAE9C,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,IAAI,EAAE,CAAC;IACtC,MAAM,KAAK,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,YAAY,CAAC,GAAG,SAAS,CAAC,CAAC;IAEzE,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;QACf,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QAC5C,OAAO;IACX,CAAC;IAED,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACrB,OAAO,CAAC,GAAG,CAAC,qCAAqC,IAAI,QAAQ,CAAC,CAAC;QAC/D,OAAO;IACX,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,wBAAwB,IAAI,eAAe,CAAC,CAAC;IAEzD,KAAK,MAAM,MAAM,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,OAAO,EAAE,CAAC,GAAG,QAAQ,CAAC,CAAC;QAC1F,OAAO,CAAC,GAAG,CAAC,SAAS,MAAM,CAAC,IAAI,KAAK,GAAG,YAAY,CAAC,CAAC;IAC1D,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,4CAA4C,CAAC,CAAC;AAC9D,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"stale.js","sourceRoot":"","sources":["../../src/commands/stale.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"tension.d.ts","sourceRoot":"","sources":["../../src/commands/tension.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAgHpC,eAAO,MAAM,cAAc,SAwLrB,CAAC"}
1
+ {"version":3,"file":"tension.d.ts","sourceRoot":"","sources":["../../src/commands/tension.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAuIpC,eAAO,MAAM,cAAc,SAwLrB,CAAC"}
@@ -8,8 +8,9 @@
8
8
  * See: treebird-internal/collab/DESIGN_security_pipeline_ssan_srlk.md
9
9
  */
10
10
  import { Command } from 'commander';
11
- import { execSync } from 'child_process';
11
+ import { execFileSync } from 'child_process';
12
12
  import { getStorage } from '../storage/index.js';
13
+ import { validateFilePath } from '../lib/security.js';
13
14
  // Security-sensitive file patterns
14
15
  const SECURITY_PATTERNS = [
15
16
  /\.env$/i,
@@ -23,7 +24,7 @@ const SECURITY_PATTERNS = [
23
24
  ];
24
25
  function getCurrentBranch() {
25
26
  try {
26
- return execSync('git rev-parse --abbrev-ref HEAD', { encoding: 'utf-8' }).trim();
27
+ return execFileSync('git', ['rev-parse', '--abbrev-ref', 'HEAD'], { encoding: 'utf-8' }).trim();
27
28
  }
28
29
  catch {
29
30
  throw new Error('Not in a git repository');
@@ -31,7 +32,10 @@ function getCurrentBranch() {
31
32
  }
32
33
  function getRepoName() {
33
34
  try {
34
- const remote = execSync('git remote get-url origin 2>/dev/null', { encoding: 'utf-8' }).trim();
35
+ const remote = execFileSync('git', ['remote', 'get-url', 'origin'], {
36
+ encoding: 'utf-8',
37
+ stdio: ['ignore', 'pipe', 'ignore']
38
+ }).trim();
35
39
  const match = remote.match(/\/([^/]+?)(?:\.git)?$/);
36
40
  return match ? match[1] : process.cwd().split('/').pop() || 'unknown';
37
41
  }
@@ -57,9 +61,24 @@ function calculateSeverity(conflictingBranches, isSecurityFile) {
57
61
  function getGitBlameOwner(filepath) {
58
62
  try {
59
63
  // Get the author who owns the most lines
60
- const blame = execSync(`git blame --porcelain "${filepath}" 2>/dev/null | grep "^author " | sort | uniq -c | sort -rn | head -1`, { encoding: 'utf-8' }).trim();
61
- const match = blame.match(/^\s*\d+\s+author\s+(.+)$/);
62
- return match ? match[1] : undefined;
64
+ const safePath = validateFilePath(filepath);
65
+ const blameOutput = execFileSync('git', ['blame', '--porcelain', '--', safePath], { encoding: 'utf-8', stdio: ['ignore', 'pipe', 'ignore'] });
66
+ const counts = new Map();
67
+ for (const line of blameOutput.split('\n')) {
68
+ if (!line.startsWith('author '))
69
+ continue;
70
+ const author = line.slice('author '.length).trim();
71
+ counts.set(author, (counts.get(author) || 0) + 1);
72
+ }
73
+ let topAuthor;
74
+ let topCount = 0;
75
+ for (const [author, count] of counts) {
76
+ if (count > topCount) {
77
+ topAuthor = author;
78
+ topCount = count;
79
+ }
80
+ }
81
+ return topAuthor;
63
82
  }
64
83
  catch {
65
84
  return undefined;
@@ -67,7 +86,8 @@ function getGitBlameOwner(filepath) {
67
86
  }
68
87
  function getLastModified(filepath) {
69
88
  try {
70
- const log = execSync(`git log -1 --format="%aI" -- "${filepath}" 2>/dev/null`, { encoding: 'utf-8' }).trim();
89
+ const safePath = validateFilePath(filepath);
90
+ const log = execFileSync('git', ['log', '-1', '--format=%aI', '--', safePath], { encoding: 'utf-8', stdio: ['ignore', 'pipe', 'ignore'] }).trim();
71
91
  return log || undefined;
72
92
  }
73
93
  catch {
@@ -1 +1 @@
1
- {"version":3,"file":"tension.js","sourceRoot":"","sources":["../../src/commands/tension.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"tension.js","sourceRoot":"","sources":["../../src/commands/tension.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"torrent.d.ts","sourceRoot":"","sources":["../../src/commands/torrent.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA8EpC,eAAO,MAAM,cAAc,SACyD,CAAC"}
1
+ {"version":3,"file":"torrent.d.ts","sourceRoot":"","sources":["../../src/commands/torrent.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAgFpC,eAAO,MAAM,cAAc,SACyD,CAAC"}
@@ -5,29 +5,31 @@
5
5
  * BitTorrent-inspired approach: tasks are "seeded" by one agent, "downloaded" by others.
6
6
  */
7
7
  import { Command } from 'commander';
8
- import { execSync } from 'child_process';
8
+ import { execFileSync } from 'child_process';
9
9
  import { getStorage } from '../storage/index.js';
10
+ import { validateTaskId } from '../lib/security.js';
10
11
  // Config
11
12
  const HUB_URL = process.env.HUB_URL || 'https://hub.treebird.uk';
12
13
  function getCurrentBranch() {
13
14
  try {
14
- return execSync('git rev-parse --abbrev-ref HEAD', { encoding: 'utf-8' }).trim();
15
+ return execFileSync('git', ['rev-parse', '--abbrev-ref', 'HEAD'], { encoding: 'utf-8' }).trim();
15
16
  }
16
17
  catch {
17
18
  throw new Error('Not in a git repository');
18
19
  }
19
20
  }
20
21
  function createBranchForTask(taskId) {
21
- const branchName = `task/${taskId}`;
22
+ const safeTaskId = validateTaskId(taskId);
23
+ const branchName = `task/${safeTaskId}`;
22
24
  try {
23
25
  // Check if branch exists
24
- execSync(`git rev-parse --verify ${branchName}`, { encoding: 'utf-8', stdio: 'pipe' });
26
+ execFileSync('git', ['rev-parse', '--verify', branchName], { encoding: 'utf-8', stdio: 'pipe' });
25
27
  console.log(` Branch ${branchName} already exists, checking out...`);
26
- execSync(`git checkout ${branchName}`, { encoding: 'utf-8' });
28
+ execFileSync('git', ['checkout', branchName], { encoding: 'utf-8' });
27
29
  }
28
30
  catch {
29
31
  // Branch doesn't exist, create it
30
- execSync(`git checkout -b ${branchName}`, { encoding: 'utf-8' });
32
+ execFileSync('git', ['checkout', '-b', branchName], { encoding: 'utf-8' });
31
33
  }
32
34
  }
33
35
  /**
@@ -70,25 +72,26 @@ torrentCommand
70
72
  .option('-a, --agent <agent>', 'Agent claiming this task')
71
73
  .option('-p, --parent <parent-task>', 'Parent task ID (for nested decomposition)')
72
74
  .action(async (taskId, options) => {
75
+ const safeTaskId = validateTaskId(taskId);
73
76
  const storage = await getStorage();
74
77
  if (!await storage.isInitialized()) {
75
78
  console.error('❌ Spidersan not initialized. Run: spidersan init');
76
79
  process.exit(1);
77
80
  }
78
- const branchName = `task/${taskId}`;
81
+ const branchName = `task/${safeTaskId}`;
79
82
  const agent = options.agent || process.env.SPIDERSAN_AGENT || 'unknown';
80
- const parentTaskId = options.parent || getParentTaskId(taskId);
83
+ const parentTaskId = options.parent || getParentTaskId(safeTaskId);
81
84
  console.log(`
82
85
  🔄 TASK TORRENTING: Create Branch
83
86
  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
84
- Task: ${taskId}
87
+ Task: ${safeTaskId}
85
88
  Branch: ${branchName}
86
89
  Agent: ${agent}
87
90
  Parent: ${parentTaskId || '(none)'}
88
91
  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
89
92
  `);
90
93
  // Create git branch
91
- createBranchForTask(taskId);
94
+ createBranchForTask(safeTaskId);
92
95
  console.log(`✅ Created and checked out: ${branchName}`);
93
96
  // Register in Spidersan
94
97
  const existing = await storage.get(branchName);
@@ -111,7 +114,7 @@ Parent: ${parentTaskId || '(none)'}
111
114
  console.log(`✅ Registered in Spidersan`);
112
115
  // Try to notify Hub
113
116
  try {
114
- await fetch(`${HUB_URL}/api/tasks/${taskId}/claim`, {
117
+ await fetch(`${HUB_URL}/api/tasks/${safeTaskId}/claim`, {
115
118
  method: 'POST',
116
119
  headers: { 'Content-Type': 'application/json' },
117
120
  body: JSON.stringify({ agent, branch: branchName })
@@ -125,7 +128,7 @@ Parent: ${parentTaskId || '(none)'}
125
128
  💡 Next steps:
126
129
  1. Make your changes
127
130
  2. git add && git commit
128
- 3. spidersan torrent complete ${taskId}
131
+ 3. spidersan torrent complete ${safeTaskId}
129
132
  `);
130
133
  });
131
134
  // Subcommand: torrent status
@@ -199,18 +202,19 @@ torrentCommand
199
202
  .option('-a, --agent <agent>', 'Agent completing this task')
200
203
  .action(async (taskId, options) => {
201
204
  const storage = await getStorage();
202
- const branchName = `task/${taskId}`;
205
+ const safeTaskId = validateTaskId(taskId);
206
+ const branchName = `task/${safeTaskId}`;
203
207
  const agent = options.agent || process.env.SPIDERSAN_AGENT || 'unknown';
204
208
  const branch = await storage.get(branchName);
205
209
  if (!branch) {
206
210
  console.error(`❌ Task branch not found: ${branchName}`);
207
- console.log(` Run: spidersan torrent create ${taskId}`);
211
+ console.log(` Run: spidersan torrent create ${safeTaskId}`);
208
212
  process.exit(1);
209
213
  }
210
214
  // Mark as completed
211
215
  await storage.update(branchName, { status: 'completed' });
212
216
  console.log(`
213
- 🎉 TASK COMPLETE: ${taskId}
217
+ 🎉 TASK COMPLETE: ${safeTaskId}
214
218
  ━━━━━━━━━━━━━━━━━━━━━━━━━━
215
219
  Branch: ${branchName}
216
220
  Agent: ${agent}
@@ -230,7 +234,7 @@ Files: ${branch.files.length}
230
234
  }
231
235
  // Try to notify Hub
232
236
  try {
233
- await fetch(`${HUB_URL}/api/tasks/${taskId}/complete`, {
237
+ await fetch(`${HUB_URL}/api/tasks/${safeTaskId}/complete`, {
234
238
  method: 'POST',
235
239
  headers: { 'Content-Type': 'application/json' },
236
240
  body: JSON.stringify({ agent, branch: branchName })
@@ -397,17 +401,18 @@ torrentCommand
397
401
  .option('-a, --agent <agent>', 'Agent creating the decomposition')
398
402
  .action(async (parentId, options) => {
399
403
  const storage = await getStorage();
404
+ const safeParentId = validateTaskId(parentId);
400
405
  const count = parseInt(options.count || '3', 10);
401
406
  const agent = options.agent || process.env.SPIDERSAN_AGENT || 'unknown';
402
407
  const letters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
403
408
  console.log(`
404
- 🔀 DECOMPOSING: ${parentId}
409
+ 🔀 DECOMPOSING: ${safeParentId}
405
410
  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
406
411
  Creating ${count} child tasks...
407
412
  `);
408
413
  const created = [];
409
414
  for (let i = 0; i < Math.min(count, 26); i++) {
410
- const childId = `${parentId}-${letters[i]}`;
415
+ const childId = `${safeParentId}-${letters[i]}`;
411
416
  const branchName = `task/${childId}`;
412
417
  // Register child task (don't create git branch, just register)
413
418
  await storage.register({