@skrr-ai/cli 0.1.36 → 0.1.37

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 (152) hide show
  1. package/README.md +17 -4
  2. package/dist/commands/agents/actions/create.d.ts +5 -0
  3. package/dist/commands/agents/actions/create.js +26 -0
  4. package/dist/commands/agents/actions/update.d.ts +5 -0
  5. package/dist/commands/agents/actions/update.js +24 -0
  6. package/dist/commands/agents/api-actions/add.d.ts +41 -0
  7. package/dist/commands/agents/api-actions/add.js +202 -0
  8. package/dist/commands/agents/api-actions/index.d.ts +28 -0
  9. package/dist/commands/agents/api-actions/index.js +77 -0
  10. package/dist/commands/agents/api-actions/remove.d.ts +14 -0
  11. package/dist/commands/agents/api-actions/remove.js +36 -0
  12. package/dist/commands/agents/avatar/default/apply.d.ts +25 -0
  13. package/dist/commands/agents/avatar/default/apply.js +56 -0
  14. package/dist/commands/agents/avatar/default/index.d.ts +18 -0
  15. package/dist/commands/agents/avatar/default/index.js +44 -0
  16. package/dist/commands/agents/avatar/default/set.d.ts +23 -0
  17. package/dist/commands/agents/avatar/default/set.js +95 -0
  18. package/dist/commands/agents/avatar/library/delete.d.ts +20 -0
  19. package/dist/commands/agents/avatar/library/delete.js +47 -0
  20. package/dist/commands/agents/avatar/library/index.d.ts +16 -0
  21. package/dist/commands/agents/avatar/library/index.js +56 -0
  22. package/dist/commands/agents/avatar/presets.d.ts +19 -0
  23. package/dist/commands/agents/avatar/presets.js +56 -0
  24. package/dist/commands/agents/categories/create.d.ts +14 -0
  25. package/dist/commands/agents/categories/create.js +46 -0
  26. package/dist/commands/agents/categories/delete.d.ts +13 -0
  27. package/dist/commands/agents/categories/delete.js +33 -0
  28. package/dist/commands/agents/categories/index.d.ts +20 -0
  29. package/dist/commands/agents/categories/index.js +82 -0
  30. package/dist/commands/agents/categories/update.d.ts +22 -0
  31. package/dist/commands/agents/categories/update.js +59 -0
  32. package/dist/commands/agents/create.d.ts +10 -0
  33. package/dist/commands/agents/create.js +57 -3
  34. package/dist/commands/agents/ensure-default.d.ts +27 -0
  35. package/dist/commands/agents/ensure-default.js +65 -0
  36. package/dist/commands/agents/mute.d.ts +16 -0
  37. package/dist/commands/agents/mute.js +38 -0
  38. package/dist/commands/agents/pin.d.ts +16 -0
  39. package/dist/commands/agents/pin.js +38 -0
  40. package/dist/commands/agents/tools/auth.d.ts +19 -0
  41. package/dist/commands/agents/tools/auth.js +41 -0
  42. package/dist/commands/agents/tools/calls.d.ts +18 -0
  43. package/dist/commands/agents/tools/calls.js +54 -0
  44. package/dist/commands/agents/tools/index.d.ts +20 -0
  45. package/dist/commands/agents/tools/index.js +77 -0
  46. package/dist/commands/agents/unmute.d.ts +16 -0
  47. package/dist/commands/agents/unmute.js +38 -0
  48. package/dist/commands/agents/unpin.d.ts +16 -0
  49. package/dist/commands/agents/unpin.js +38 -0
  50. package/dist/commands/agents/update.d.ts +12 -0
  51. package/dist/commands/agents/update.js +64 -3
  52. package/dist/commands/followups/act.d.ts +22 -0
  53. package/dist/commands/followups/act.js +102 -0
  54. package/dist/commands/followups/cancel.d.ts +17 -0
  55. package/dist/commands/followups/cancel.js +40 -0
  56. package/dist/commands/followups/checkin.d.ts +27 -0
  57. package/dist/commands/followups/checkin.js +107 -0
  58. package/dist/commands/followups/list.d.ts +24 -0
  59. package/dist/commands/followups/list.js +90 -0
  60. package/dist/commands/followups/remind.d.ts +26 -0
  61. package/dist/commands/followups/remind.js +106 -0
  62. package/dist/commands/followups/reschedule.d.ts +15 -0
  63. package/dist/commands/followups/reschedule.js +48 -0
  64. package/dist/commands/followups/resolve.d.ts +23 -0
  65. package/dist/commands/followups/resolve.js +54 -0
  66. package/dist/commands/followups/show.d.ts +12 -0
  67. package/dist/commands/followups/show.js +45 -0
  68. package/dist/commands/followups/watch.d.ts +51 -0
  69. package/dist/commands/followups/watch.js +207 -0
  70. package/dist/commands/goals/labels/add.js +19 -2
  71. package/dist/commands/goals/labels/remove.js +22 -2
  72. package/dist/commands/labels/list.d.ts +24 -1
  73. package/dist/commands/labels/list.js +62 -19
  74. package/dist/commands/memory/governance/index.d.ts +21 -0
  75. package/dist/commands/memory/governance/index.js +64 -0
  76. package/dist/commands/memory/governance/set.d.ts +24 -0
  77. package/dist/commands/memory/governance/set.js +95 -0
  78. package/dist/commands/memory/provenance.d.ts +18 -0
  79. package/dist/commands/memory/provenance.js +66 -0
  80. package/dist/commands/spaces/create.d.ts +3 -0
  81. package/dist/commands/spaces/create.js +32 -2
  82. package/dist/commands/spaces/labels/add.js +19 -2
  83. package/dist/commands/spaces/labels/remove.js +22 -2
  84. package/dist/commands/spaces/show.js +2 -0
  85. package/dist/commands/spaces/update.d.ts +5 -0
  86. package/dist/commands/spaces/update.js +41 -4
  87. package/dist/commands/spaces/workflows/lifecycle-diagnostics.d.ts +11 -0
  88. package/dist/commands/spaces/workflows/lifecycle-diagnostics.js +45 -0
  89. package/dist/commands/tasks/complete.d.ts +1 -0
  90. package/dist/commands/tasks/complete.js +8 -1
  91. package/dist/commands/tasks/create.d.ts +3 -0
  92. package/dist/commands/tasks/create.js +34 -2
  93. package/dist/commands/tasks/expectations/assess.d.ts +11 -0
  94. package/dist/commands/tasks/expectations/assess.js +85 -14
  95. package/dist/commands/tasks/expectations.js +19 -2
  96. package/dist/commands/tasks/labels/attach.js +20 -3
  97. package/dist/commands/tasks/labels/detach.js +21 -3
  98. package/dist/commands/tasks/lifecycle/attach.d.ts +14 -0
  99. package/dist/commands/tasks/lifecycle/attach.js +47 -0
  100. package/dist/commands/tasks/lifecycle/definitions.d.ts +11 -0
  101. package/dist/commands/tasks/lifecycle/definitions.js +40 -0
  102. package/dist/commands/tasks/lifecycle/detach.d.ts +12 -0
  103. package/dist/commands/tasks/lifecycle/detach.js +32 -0
  104. package/dist/commands/tasks/lifecycle/history.d.ts +13 -0
  105. package/dist/commands/tasks/lifecycle/history.js +38 -0
  106. package/dist/commands/tasks/lifecycle/migrate.d.ts +12 -0
  107. package/dist/commands/tasks/lifecycle/migrate.js +29 -0
  108. package/dist/commands/tasks/lifecycle/reconcile.d.ts +11 -0
  109. package/dist/commands/tasks/lifecycle/reconcile.js +27 -0
  110. package/dist/commands/tasks/lifecycle/reopen.d.ts +13 -0
  111. package/dist/commands/tasks/lifecycle/reopen.js +34 -0
  112. package/dist/commands/tasks/lifecycle/show.d.ts +11 -0
  113. package/dist/commands/tasks/lifecycle/show.js +27 -0
  114. package/dist/commands/tasks/lifecycle/start.d.ts +12 -0
  115. package/dist/commands/tasks/lifecycle/start.js +30 -0
  116. package/dist/commands/tasks/lifecycle/transition.d.ts +15 -0
  117. package/dist/commands/tasks/lifecycle/transition.js +78 -0
  118. package/dist/commands/tasks/move.d.ts +1 -0
  119. package/dist/commands/tasks/move.js +31 -0
  120. package/dist/commands/tasks/result/submit.js +11 -1
  121. package/dist/commands/tasks/review-queue.d.ts +29 -0
  122. package/dist/commands/tasks/review-queue.js +165 -0
  123. package/dist/commands/tasks/show.js +42 -0
  124. package/dist/commands/tasks/update.d.ts +1 -0
  125. package/dist/commands/tasks/update.js +47 -0
  126. package/dist/lib/agent-actions.d.ts +36 -10
  127. package/dist/lib/agent-actions.js +63 -9
  128. package/dist/lib/agent-config.d.ts +11 -0
  129. package/dist/lib/agent-config.js +85 -3
  130. package/dist/lib/agent-pin-mute.d.ts +24 -0
  131. package/dist/lib/agent-pin-mute.js +17 -0
  132. package/dist/lib/agent-visual-refs.d.ts +6 -0
  133. package/dist/lib/agent-visual-refs.js +142 -0
  134. package/dist/lib/first-party-harness-agent.js +7 -0
  135. package/dist/lib/followups.d.ts +107 -0
  136. package/dist/lib/followups.js +102 -0
  137. package/dist/lib/label-ref.d.ts +95 -0
  138. package/dist/lib/label-ref.js +163 -0
  139. package/dist/lib/label-scope.d.ts +2 -2
  140. package/dist/lib/label-scope.js +3 -3
  141. package/dist/lib/task-closure.d.ts +32 -0
  142. package/dist/lib/task-closure.js +106 -0
  143. package/dist/lib/task-lifecycle-output.d.ts +14 -0
  144. package/dist/lib/task-lifecycle-output.js +101 -0
  145. package/dist/lib/tasks.d.ts +3 -0
  146. package/dist/lib/tasks.js +31 -0
  147. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/harnessTrust.js +4 -0
  148. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/harnessTrust.js +4 -0
  149. package/dist/node_modules/@skrr-ai/auth-core/package.json +1 -1
  150. package/dist/node_modules/@skrr-ai/data-provider/index.js +5079 -4546
  151. package/oclif.manifest.json +20216 -16002
  152. package/package.json +16 -4
@@ -2,7 +2,7 @@
2
2
  /**
3
3
  * Shared plumbing for the unified label commands (`skrr labels …`).
4
4
  *
5
- * Labels are anchored to exactly one scope — a user, a space, or a workspace —
5
+ * Labels are anchored to exactly one scope — a user or a workspace —
6
6
  * via the `(scope, scopeId)` pair. That pair is simultaneously the uniqueness
7
7
  * key and the permission boundary server-side (see
8
8
  * `api/server/services/Labels/LabelService.js`), so every label command has to
@@ -16,7 +16,7 @@ exports.normalizeLabelColor = normalizeLabelColor;
16
16
  exports.resolveLabelScope = resolveLabelScope;
17
17
  exports.resolveApplicableTo = resolveApplicableTo;
18
18
  const core_1 = require("@oclif/core");
19
- exports.LABEL_SCOPES = ['user', 'space', 'workspace'];
19
+ exports.LABEL_SCOPES = ['user', 'workspace'];
20
20
  exports.LABEL_APPLICABLE = ['task', 'space', 'goal', 'routine'];
21
21
  /**
22
22
  * The server stores colors as bare 6-hex (`api/server/routes/labels.js` Zod is
@@ -44,7 +44,7 @@ exports.labelScopeFlags = {
44
44
  function resolveLabelScope(flags) {
45
45
  const scope = (flags.scope ?? 'user');
46
46
  const scopeId = flags['scope-id'];
47
- if ((scope === 'space' || scope === 'workspace') && !scopeId) {
47
+ if (scope === 'workspace' && !scopeId) {
48
48
  throw new Error(`--scope-id is required for --scope ${scope}.`);
49
49
  }
50
50
  if (scope === 'user' && scopeId) {
@@ -0,0 +1,32 @@
1
+ import type { TaskClosureEvaluation } from '@skrr-ai/data-provider';
2
+ /**
3
+ * Render "where does this Task actually stand" for every surface that should
4
+ * say it.
5
+ *
6
+ * ONE renderer, because the failure this exists to fix was several surfaces each
7
+ * asserting a closure state none of them had checked: `tasks result submit`
8
+ * printed a hard-coded "it is ready for review", the server wrote a
9
+ * `ready_for_review` Update to match, and the managed instructions told the
10
+ * agent to read a status the response did not carry. Three confident voices,
11
+ * one unchecked claim.
12
+ *
13
+ * So the rule here is narrow and absolute: this function says only what the
14
+ * evaluation says. If the evaluation is absent or could not run, it says THAT —
15
+ * it never falls back to an optimistic sentence, because the optimistic sentence
16
+ * is the bug.
17
+ */
18
+ export type ClosureLike = TaskClosureEvaluation | {
19
+ unavailable: true;
20
+ reason?: string;
21
+ } | undefined;
22
+ /**
23
+ * The full account, for the moment a caller has just written something and is
24
+ * deciding what to do next.
25
+ *
26
+ * Every unmet Expectation is NAMED. The ids alone (`e1`, `e2`) are what the
27
+ * gate's own details carried for a while, and they are unusable on their own —
28
+ * the whole point is to be able to act without a second lookup.
29
+ */
30
+ export declare function closureReport(closure: ClosureLike): string[];
31
+ /** `met (agent)` vs `met (you)` — whose judgement settled it, never hidden. */
32
+ export declare function describeAssessor(kind: string | null | undefined): string;
@@ -0,0 +1,106 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.closureReport = closureReport;
4
+ exports.describeAssessor = describeAssessor;
5
+ function isUnavailable(closure) {
6
+ return Boolean(closure && closure.unavailable);
7
+ }
8
+ const SHORT_BLOCKER = {
9
+ TASK_RESULT_REQUIRED: 'no Result submitted',
10
+ TASK_CURRENT_RESULT_MISSING: 'the current Result does not resolve',
11
+ TASK_RESULT_SPEC_VERSION_MISMATCH: 'the Result answers an older specification',
12
+ TASK_RESULT_CHANGES_REQUESTED: 'a reviewer requested changes',
13
+ TASK_RESULT_REVIEW_REQUIRED: 'an independent accepted Review is required',
14
+ };
15
+ /**
16
+ * The full account, for the moment a caller has just written something and is
17
+ * deciding what to do next.
18
+ *
19
+ * Every unmet Expectation is NAMED. The ids alone (`e1`, `e2`) are what the
20
+ * gate's own details carried for a while, and they are unusable on their own —
21
+ * the whole point is to be able to act without a second lookup.
22
+ */
23
+ function closureReport(closure) {
24
+ if (!closure)
25
+ return ['Closure state: not reported by this call.'];
26
+ if (isUnavailable(closure)) {
27
+ return [
28
+ 'Closure state could not be evaluated. That is a statement about this read,',
29
+ 'not about the work — run `skrr tasks expectations <task-id>` to ask directly.',
30
+ ];
31
+ }
32
+ const lines = [];
33
+ const exp = closure.expectations;
34
+ /*
35
+ * The degraded note comes FIRST, and before the closable shortcut.
36
+ *
37
+ * An unreadable assessment ledger makes the gate fail OPEN — deliberately, so
38
+ * a Mongo blip cannot create a Task nothing can close — which means `closable`
39
+ * can be true precisely because a check did not run. Reporting only "nothing
40
+ * is outstanding" there would launder an infrastructure failure into a clean
41
+ * bill of health, which is the same class of silence this whole file exists to
42
+ * remove.
43
+ */
44
+ if (exp?.degraded === 'assessments_unreadable' || closure.degraded === 'assessments_unreadable') {
45
+ lines.push('Expectation assessments could not be read; that check was skipped, not passed.');
46
+ }
47
+ if (closure.closable) {
48
+ lines.push('Nothing is outstanding — this Task can close.');
49
+ return lines;
50
+ }
51
+ if (exp && exp.total > 0) {
52
+ /*
53
+ * "Settled," not "met" — a waived Expectation was judged no longer owed,
54
+ * which is a different fact from done. The count names waivers when any
55
+ * exist so a scope change never reads as completed work.
56
+ */
57
+ const settled = exp.settledCount ?? exp.settled?.length ?? exp.met;
58
+ const waivedNote = exp.waived ? ` (${exp.waived} waived)` : '';
59
+ lines.push(`Expectations: ${settled} of ${exp.total} settled${waivedNote}.`);
60
+ for (const row of exp.unmet) {
61
+ lines.push(` ${row.id} ${truncate(row.sentence || row.text || '(no text)', 76)}`);
62
+ }
63
+ }
64
+ for (const blocker of closure.blockers) {
65
+ if (blocker.code === 'TASK_EXPECTATIONS_NOT_MET')
66
+ continue;
67
+ lines.push(SHORT_BLOCKER[blocker.code] ? capitalize(SHORT_BLOCKER[blocker.code]) + '.' : blocker.message);
68
+ }
69
+ if (exp && exp.unmet.length > 0) {
70
+ lines.push('');
71
+ lines.push('Settle each with `skrr tasks expectations assess <task-id> <expectation-id>');
72
+ lines.push(' --decision met|waived --reason "..."`, or review the whole space with');
73
+ lines.push(' `skrr tasks review-queue --space <space-id>`.');
74
+ }
75
+ /*
76
+ * Everything else is advisory — stamped onto `resolution.closure` if the
77
+ * Task closes over it. The one refusal left is an owner-declared required
78
+ * Review, and only for someone who is not the owner; when that blocker is
79
+ * present, say the narrower truth.
80
+ */
81
+ const reviewRequired = closure.blockers.some((b) => b.code === 'TASK_RESULT_REVIEW_REQUIRED');
82
+ lines.push('');
83
+ lines.push(reviewRequired
84
+ ? 'Only an accepted independent Review — or the Task owner closing directly — settles this. The rest is recorded on resolution.closure.'
85
+ : 'Closing anyway is allowed — all of this is recorded on resolution.closure.');
86
+ return lines;
87
+ }
88
+ /** `met (agent)` vs `met (you)` — whose judgement settled it, never hidden. */
89
+ function describeAssessor(kind) {
90
+ if (kind === 'agent')
91
+ return 'agent';
92
+ if (kind === 'human')
93
+ return 'person';
94
+ if (kind === 'system')
95
+ return 'system';
96
+ if (kind === 'integration')
97
+ return 'integration';
98
+ return 'unattributed';
99
+ }
100
+ function truncate(value, max) {
101
+ const flat = value.replace(/\s+/g, ' ').trim();
102
+ return flat.length > max ? `${flat.slice(0, max - 1)}…` : flat;
103
+ }
104
+ function capitalize(value) {
105
+ return value.charAt(0).toUpperCase() + value.slice(1);
106
+ }
@@ -0,0 +1,14 @@
1
+ import type { TaskLifecycleHistoryResponse, TaskLifecycleResponse, TaskLifecycleTransitionResponse } from '@skrr-ai/data-provider';
2
+ /**
3
+ * Render the Task Lifecycle response — the projection, its stages in protocol
4
+ * order, and the transitions the waiting stage currently declares.
5
+ */
6
+ export declare function renderTaskLifecycleSummary(response: TaskLifecycleResponse, log: (line: string) => void): void;
7
+ /** Render the outcome of a lifecycle transition call. */
8
+ export declare function renderLifecycleTransitionResult(response: TaskLifecycleTransitionResponse, log: (line: string) => void): void;
9
+ /**
10
+ * Render the durable lifecycle event stream — every generation's transitions,
11
+ * gates and run events, newest first. `lifecycle show` answers where the Task
12
+ * IS; this answers how it got there.
13
+ */
14
+ export declare function renderLifecycleHistory(response: TaskLifecycleHistoryResponse, log: (line: string) => void): void;
@@ -0,0 +1,101 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.renderTaskLifecycleSummary = renderTaskLifecycleSummary;
4
+ exports.renderLifecycleTransitionResult = renderLifecycleTransitionResult;
5
+ exports.renderLifecycleHistory = renderLifecycleHistory;
6
+ /**
7
+ * Render the Task Lifecycle response — the projection, its stages in protocol
8
+ * order, and the transitions the waiting stage currently declares.
9
+ */
10
+ function renderTaskLifecycleSummary(response, log) {
11
+ const lifecycle = response.lifecycle;
12
+ if (!lifecycle) {
13
+ log('No lifecycle is attached to this Task.');
14
+ log('Attach one: skrr tasks lifecycle attach <task-id> --pack finding');
15
+ return;
16
+ }
17
+ log(`Lifecycle: ${lifecycle.status} (v${lifecycle.version}, generation ${lifecycle.generation}, revision ${lifecycle.revision})` +
18
+ (lifecycle.packId ? ` — pack ${lifecycle.packId}` : ''));
19
+ if (response.run)
20
+ log(`Run: ${response.run.id} — ${response.run.status}`);
21
+ for (const stage of response.stages || []) {
22
+ const marker = stage.key === lifecycle.currentStageKey ? '>' : ' ';
23
+ const state = stage.status
24
+ ? ` — ${stage.status}${stage.outcome ? `/${stage.outcome}` : ''}`
25
+ : '';
26
+ log(`${marker} ${stage.label || stage.key}${state}`);
27
+ }
28
+ if (response.gate) {
29
+ log('');
30
+ log(`Closure gate: ${response.gate.message}`);
31
+ }
32
+ const transitions = response.allowedTransitions || [];
33
+ const waiting = response.stage?.waitingFor;
34
+ if (response.stage && transitions.length) {
35
+ log('');
36
+ log(`Stage "${response.stage.nodeKey}" is waiting${waiting?.nextActor ? ` on ${waiting.nextActor}` : ''}. Legal transitions:`);
37
+ for (const transition of transitions) {
38
+ const needs = [
39
+ ...(transition.requires?.fields || []).map((f) => `payload.${f}`),
40
+ transition.requires?.updateType ? `${transition.requires.updateType} update` : undefined,
41
+ transition.requires?.evidence
42
+ ? `${transition.requires.evidence} evidence ref(s)`
43
+ : undefined,
44
+ transition.requires?.deliverableRef ? 'deliverable ref' : undefined,
45
+ ].filter(Boolean);
46
+ log(` ${transition.id} -> ${transition.outcome}${transition.label ? ` (${transition.label})` : ''}${needs.length ? ` — needs ${needs.join(', ')}` : ''}`);
47
+ }
48
+ }
49
+ if (response.pendingEffects?.length) {
50
+ log('');
51
+ log(`${response.pendingEffects.length} effect(s) pending repair:`);
52
+ for (const effect of response.pendingEffects) {
53
+ log(` ${effect.kind}${effect.lastError ? ` — ${effect.lastError}` : ''}`);
54
+ }
55
+ }
56
+ if (lifecycle.statusDrift) {
57
+ log(`Status drift: stage expects ${lifecycle.statusDrift.expected}, Task shows ${lifecycle.statusDrift.actual}.`);
58
+ }
59
+ }
60
+ /** Render the outcome of a lifecycle transition call. */
61
+ function renderLifecycleTransitionResult(response, log) {
62
+ log(`Transition ${response.status}${response.code ? ` (${response.code})` : ''}.`);
63
+ if (response.message)
64
+ log(response.message);
65
+ for (const effect of response.effects || []) {
66
+ log(` effect ${effect.kind}: ${effect.status}${effect.ref ? ` -> ${effect.ref}` : ''}${effect.error ? ` — ${effect.error}` : ''}`);
67
+ }
68
+ if (response.gate)
69
+ log(`Gate: ${response.gate.message}`);
70
+ if (response.lifecycle) {
71
+ log(`Lifecycle: ${response.lifecycle.status}, stage ${response.lifecycle.currentStageKey ?? '—'}, revision ${response.lifecycle.revision}.`);
72
+ }
73
+ }
74
+ /**
75
+ * Render the durable lifecycle event stream — every generation's transitions,
76
+ * gates and run events, newest first. `lifecycle show` answers where the Task
77
+ * IS; this answers how it got there.
78
+ */
79
+ function renderLifecycleHistory(response, log) {
80
+ if (!response.events.length) {
81
+ log('No lifecycle events recorded for this Task.');
82
+ return;
83
+ }
84
+ for (const event of response.events) {
85
+ const parts = [
86
+ event.at,
87
+ event.type,
88
+ event.generation !== undefined ? `gen ${event.generation}` : undefined,
89
+ event.transitionId,
90
+ event.status,
91
+ event.outcome,
92
+ event.code,
93
+ ].filter(Boolean);
94
+ log(parts.join(' '));
95
+ if (event.message)
96
+ log(` ${event.message}`);
97
+ }
98
+ if (response.truncated) {
99
+ log(`— truncated at the event limit; re-query with a higher --limit or --before.`);
100
+ }
101
+ }
@@ -66,6 +66,9 @@ export type TaskCreateFlagValues = {
66
66
  tag?: string[];
67
67
  'label-id'?: string[];
68
68
  worktree?: boolean;
69
+ 'lifecycle-definition'?: string;
70
+ 'lifecycle-version'?: string;
71
+ 'lifecycle-pack'?: string;
69
72
  };
70
73
  /**
71
74
  * Map the tri-state `--worktree` flag to the `executionIsolation` value.
package/dist/lib/tasks.js CHANGED
@@ -241,6 +241,22 @@ function normalizeTaskCreateJsonAliases(body) {
241
241
  }
242
242
  return normalized;
243
243
  }
244
+ /**
245
+ * Assemble the create-time lifecycle binding from its three flags. Returns
246
+ * undefined when none are set so `mergeDefined` never writes an empty object.
247
+ */
248
+ function lifecycleBindingFromFlags(flags) {
249
+ const definitionId = flags['lifecycle-definition'];
250
+ const versionId = flags['lifecycle-version'];
251
+ const packId = flags['lifecycle-pack'];
252
+ if (!definitionId && !versionId && !packId)
253
+ return undefined;
254
+ return {
255
+ ...(definitionId ? { definitionId } : {}),
256
+ ...(versionId ? { versionId } : {}),
257
+ ...(packId ? { packId } : {}),
258
+ };
259
+ }
244
260
  function buildTaskCreatePayload(body, flags = {}) {
245
261
  const payload = (0, prompt_1.mergeDefined)(normalizeTaskCreateJsonAliases(body), {
246
262
  templateId: flags.template,
@@ -275,6 +291,7 @@ function buildTaskCreatePayload(body, flags = {}) {
275
291
  // Worktree isolation opt-in. --worktree ⇒ 'ephemeral', --no-worktree ⇒
276
292
  // 'shared', omitted ⇒ undefined (inherit space policy / global default).
277
293
  executionIsolation: executionIsolationFromWorktreeFlag(flags.worktree),
294
+ lifecycle: lifecycleBindingFromFlags(flags),
278
295
  });
279
296
  applyDaemonSessionDefaults(payload);
280
297
  normalizeStringField(payload, 'externalKey', 300);
@@ -349,6 +366,20 @@ function validateTaskCreatePayload(payload) {
349
366
  if (payload.templateId !== undefined && !isBoundedString(payload.templateId, 1, 100)) {
350
367
  errors.push('templateId must be a non-empty string at most 100 characters');
351
368
  }
369
+ if (payload.lifecycle !== undefined) {
370
+ const binding = payload.lifecycle;
371
+ if (!binding || typeof binding !== 'object' || Array.isArray(binding)) {
372
+ errors.push('lifecycle must be an object with definitionId, versionId, or packId');
373
+ }
374
+ else {
375
+ if (!isNonEmptyString(binding.definitionId) && !isNonEmptyString(binding.packId)) {
376
+ errors.push('lifecycle requires a definitionId or a packId');
377
+ }
378
+ if (binding.versionId !== undefined && !isNonEmptyString(binding.definitionId)) {
379
+ errors.push('lifecycle.versionId requires lifecycle.definitionId');
380
+ }
381
+ }
382
+ }
352
383
  for (const field of [
353
384
  'parentId',
354
385
  'goalId',
@@ -68,6 +68,10 @@ exports.HARNESS_TIERS = Object.freeze({
68
68
  'opencode-acp': 1,
69
69
  gemini: 1,
70
70
  'gemini-acp': 1,
71
+ // Cognition's own CLI (`devin acp`). Vendor first-party like claude/codex —
72
+ // its credential is Cognition's API key, delivered over the ACP
73
+ // `authenticate` RPC rather than env (see daemon backends/devin.ts).
74
+ devin: 1,
71
75
  ...Object.fromEntries((0, firstPartyHarness_js_1.firstPartyHarnessSpellings)().map((spelling) => [spelling, 1])),
72
76
  // --- Tier 2: reviewed open-source community harnesses ---
73
77
  goose: 2,
@@ -62,6 +62,10 @@ export const HARNESS_TIERS = Object.freeze({
62
62
  'opencode-acp': 1,
63
63
  gemini: 1,
64
64
  'gemini-acp': 1,
65
+ // Cognition's own CLI (`devin acp`). Vendor first-party like claude/codex —
66
+ // its credential is Cognition's API key, delivered over the ACP
67
+ // `authenticate` RPC rather than env (see daemon backends/devin.ts).
68
+ devin: 1,
65
69
  ...Object.fromEntries(firstPartyHarnessSpellings().map((spelling) => [spelling, 1])),
66
70
  // --- Tier 2: reviewed open-source community harnesses ---
67
71
  goose: 2,
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@skrr-ai/auth-core",
3
- "version": "0.2.1",
3
+ "version": "0.2.2",
4
4
  "main": "dist/cjs/index.js",
5
5
  "types": "dist/esm/index.d.ts",
6
6
  "exports": {