sidecar-cli 0.1.5-rc.1 → 0.1.6-beta.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.
package/README.md CHANGED
@@ -200,9 +200,9 @@ Notes, decisions, worklogs:
200
200
 
201
201
  Tasks:
202
202
 
203
- - `sidecar task add "<title>" [--description <text>] [--priority low|medium|high] [--by human|agent] [--json]`
204
- - `sidecar task done <task-id> [--by human|agent] [--json]`
205
- - `sidecar task list [--status open|done|all] [--format table|json] [--json]`
203
+ - `sidecar task create --title "<title>" --summary "<summary>" --goal "<goal>" [--type feature|bug|chore|research] [--status draft|ready|queued|running|review|blocked|done] [--priority low|medium|high] [--json]`
204
+ - `sidecar task set-status <task-id> --to draft|ready|queued|running|review|blocked|done --reason "<text>" [--by human|agent] [--session <id>] [--json]`
205
+ - `sidecar task list [--status draft|ready|queued|running|review|blocked|done|all] [--json]`
206
206
 
207
207
  Sessions:
208
208
 
@@ -434,7 +434,7 @@ sidecar context --format markdown
434
434
  sidecar session start --actor agent --name codex
435
435
  sidecar decision record --title "Use SQLite" --summary "Local-first persistence"
436
436
  sidecar worklog record --goal "init flow" --done "Implemented schema and command surface" --files src/cli.ts,src/db/schema.ts
437
- sidecar task add "Add integration tests" --priority medium --by agent
437
+ sidecar task create --title "Add integration tests" --summary "Add integration coverage for init flow" --goal "Ensure init flow has regression coverage" --priority medium
438
438
  sidecar summary refresh
439
439
  sidecar session end --summary "Initialization and recording flow implemented"
440
440
  ```
@@ -449,7 +449,7 @@ Required minimum for any code change:
449
449
  1. `sidecar context --format markdown`
450
450
  2. `sidecar worklog record --done "<what changed>" --files <paths> --by agent`
451
451
  3. if behavior/design changed: `sidecar decision record ...`
452
- 4. if follow-up exists: `sidecar task add ...`
452
+ 4. if follow-up exists: `sidecar task create ...`
453
453
  5. `sidecar summary refresh`
454
454
 
455
455
  Optional local enforcement:
@@ -489,7 +489,7 @@ When changes are made in this repo, document them in Sidecar:
489
489
  1. `sidecar context --format markdown`
490
490
  2. `sidecar worklog record --done "<what changed>" --files <paths> --by human|agent`
491
491
  3. `sidecar decision record ...` when behavior/design changes
492
- 4. `sidecar task add ...` for follow-up work
492
+ 4. `sidecar task create ...` for follow-up work
493
493
  5. `sidecar summary refresh`
494
494
 
495
495
  ## Local storage details
@@ -579,7 +579,7 @@ Standard JSON envelope:
579
579
  {
580
580
  "ok": true,
581
581
  "version": "1.0",
582
- "command": "task add",
582
+ "command": "task create",
583
583
  "data": {},
584
584
  "errors": []
585
585
  }
@@ -591,7 +591,7 @@ Failure envelope:
591
591
  {
592
592
  "ok": false,
593
593
  "version": "1.0",
594
- "command": "task add",
594
+ "command": "task create",
595
595
  "data": null,
596
596
  "errors": ["..."]
597
597
  }
package/dist/cli.js CHANGED
@@ -22,7 +22,7 @@ import { refreshSummaryFile } from './services/summary-service.js';
22
22
  import { buildContext } from './services/context-service.js';
23
23
  import { getCapabilitiesManifest } from './services/capabilities-service.js';
24
24
  import { addArtifact, listArtifacts } from './services/artifact-service.js';
25
- import { addDecision, addNote, addWorklog, getActiveSessionId, listRecentEvents } from './services/event-service.js';
25
+ import { addDecision, addNote, addWorklog, createEvent, getActiveSessionId, listRecentEvents } from './services/event-service.js';
26
26
  import { currentSession, endSession, startSession, verifySessionHygiene } from './services/session-service.js';
27
27
  import { HOOK_EVENTS, handleHookEvent, hookEventSchema, hookPayloadSchema } from './services/hook-service.js';
28
28
  import { loadPromptSpec } from './prompts/prompt-spec.js';
@@ -39,6 +39,7 @@ import { compileTaskPrompt } from './prompts/prompt-service.js';
39
39
  import { runPipelineExecution, runTaskExecution } from './services/run-orchestrator-service.js';
40
40
  import { loadRunnerPreferences } from './runners/config.js';
41
41
  import { assignTask, queueReadyTasks } from './services/task-orchestration-service.js';
42
+ import { transitionTaskStatus } from './services/task-status-service.js';
42
43
  import { buildReviewSummary, createFollowupTaskFromRun, reviewRun } from './services/run-review-service.js';
43
44
  const pkg = JSON.parse(fs.readFileSync(new URL('../package.json', import.meta.url), 'utf8'));
44
45
  const actorSchema = z.enum(['human', 'agent']);
@@ -1100,7 +1101,7 @@ task
1100
1101
  .description('List task packets')
1101
1102
  .option('--status <status>', 'draft|ready|queued|running|review|blocked|done|all', 'all')
1102
1103
  .option('--json', 'Print machine-readable JSON output')
1103
- .addHelpText('after', '\nExamples:\n $ sidecar task list\n $ sidecar task list --status open\n $ sidecar task list --json')
1104
+ .addHelpText('after', '\nExamples:\n $ sidecar task list\n $ sidecar task list --status draft\n $ sidecar task list --json')
1104
1105
  .action((opts) => {
1105
1106
  const command = 'task list';
1106
1107
  try {
@@ -1158,6 +1159,64 @@ task
1158
1159
  handleCommandError(command, Boolean(opts.json), err);
1159
1160
  }
1160
1161
  });
1162
+ task
1163
+ .command('set-status <task-id>')
1164
+ .description('Transition task packet status with validation and an audit note')
1165
+ .requiredOption('--to <status>', 'draft|ready|queued|running|review|blocked|done')
1166
+ .requiredOption('--reason <text>', 'Why this manual transition is needed')
1167
+ .option('--by <actor>', 'human|agent', 'human')
1168
+ .option('--session <session-id>', 'Session id override')
1169
+ .option('--json', 'Print machine-readable JSON output')
1170
+ .addHelpText('after', '\nExamples:\n $ sidecar task set-status T-001 --to ready --reason "Ready to queue"\n $ sidecar task set-status T-001 --to done --reason "Administrative cleanup" --by agent --json')
1171
+ .action((taskIdText, opts) => {
1172
+ const command = 'task set-status';
1173
+ try {
1174
+ const taskId = taskIdText.trim().toUpperCase();
1175
+ const toStatus = taskPacketStatusSchema.parse(opts.to);
1176
+ const reason = String(opts.reason ?? '').trim();
1177
+ if (!reason)
1178
+ fail('Reason is required');
1179
+ const by = actorSchema.parse(opts.by);
1180
+ const { db, projectId } = requireInitialized();
1181
+ const sessionId = maybeSessionId(db, projectId, opts.session);
1182
+ const result = transitionTaskStatus(resolveProjectRoot(), taskId, toStatus);
1183
+ const eventId = createEvent(db, {
1184
+ projectId,
1185
+ type: 'note',
1186
+ title: `Task ${result.task_id} status changed`,
1187
+ summary: `${result.from_status} -> ${result.to_status}: ${reason}`,
1188
+ details: {
1189
+ task_id: result.task_id,
1190
+ from_status: result.from_status,
1191
+ to_status: result.to_status,
1192
+ reason,
1193
+ command: 'task set-status',
1194
+ },
1195
+ createdBy: by,
1196
+ sessionId,
1197
+ });
1198
+ db.close();
1199
+ respondSuccess(command, Boolean(opts.json), {
1200
+ task: result,
1201
+ event: {
1202
+ id: eventId,
1203
+ type: 'note',
1204
+ title: `Task ${result.task_id} status changed`,
1205
+ summary: `${result.from_status} -> ${result.to_status}: ${reason}`,
1206
+ created_by: by,
1207
+ session_id: sessionId,
1208
+ created_at: nowIso(),
1209
+ },
1210
+ }, [
1211
+ `Updated ${result.task_id}: ${result.from_status} -> ${result.to_status}.`,
1212
+ `Reason: ${reason}`,
1213
+ `Recorded note event #${eventId}.`,
1214
+ ]);
1215
+ }
1216
+ catch (err) {
1217
+ handleCommandError(command, Boolean(opts.json), err);
1218
+ }
1219
+ });
1161
1220
  task
1162
1221
  .command('create-followup <run-id>')
1163
1222
  .description('Create a follow-up task packet from a run report')
@@ -222,6 +222,13 @@ export function getCapabilitiesManifest(version) {
222
222
  arguments: ['<task-id>'],
223
223
  options: ['--agent-role planner|builder-ui|builder-app|reviewer|tester', '--runner codex|claude', '--json'],
224
224
  },
225
+ {
226
+ name: 'set-status',
227
+ description: 'Transition task packet status with validation',
228
+ json_output: true,
229
+ arguments: ['<task-id>'],
230
+ options: ['--to draft|ready|queued|running|review|blocked|done', '--reason <text>', '--by human|agent', '--session <id>', '--json'],
231
+ },
225
232
  {
226
233
  name: 'create-followup',
227
234
  description: 'Create follow-up task from run report',
@@ -0,0 +1,33 @@
1
+ import { SidecarError } from '../lib/errors.js';
2
+ import { getTaskPacket, saveTaskPacket } from '../tasks/task-service.js';
3
+ const TASK_STATUS_TRANSITIONS = {
4
+ draft: ['ready', 'blocked', 'done'],
5
+ ready: ['draft', 'queued', 'blocked', 'done'],
6
+ queued: ['ready', 'running', 'blocked'],
7
+ running: ['ready', 'review', 'blocked'],
8
+ review: ['ready', 'blocked', 'done'],
9
+ blocked: ['ready', 'done'],
10
+ done: ['review'],
11
+ };
12
+ export function allowedTaskStatusTransitions(fromStatus) {
13
+ return TASK_STATUS_TRANSITIONS[fromStatus];
14
+ }
15
+ export function transitionTaskStatus(rootPath, taskId, toStatus) {
16
+ const task = getTaskPacket(rootPath, taskId);
17
+ const fromStatus = task.status;
18
+ if (fromStatus === toStatus) {
19
+ throw new SidecarError(`Task ${task.task_id} is already '${toStatus}'`);
20
+ }
21
+ const allowed = allowedTaskStatusTransitions(fromStatus);
22
+ if (!allowed.includes(toStatus)) {
23
+ throw new SidecarError(`Invalid status transition for ${task.task_id}: ${fromStatus} -> ${toStatus}. Allowed: ${allowed.join(', ')}`);
24
+ }
25
+ const updated = { ...task, status: toStatus };
26
+ const filePath = saveTaskPacket(rootPath, updated);
27
+ return {
28
+ task_id: task.task_id,
29
+ from_status: fromStatus,
30
+ to_status: toStatus,
31
+ path: filePath,
32
+ };
33
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sidecar-cli",
3
- "version": "0.1.5-rc.1",
3
+ "version": "0.1.6-beta.1",
4
4
  "description": "Local-first project memory and recording tool",
5
5
  "scripts": {
6
6
  "build": "npm run clean && tsc -p tsconfig.json",