@odla-ai/cli 0.42.2 → 0.43.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin.cjs +214 -66
- package/dist/bin.cjs.map +1 -1
- package/dist/bin.js +1 -1
- package/dist/{chunk-K6ATAKGR.js → chunk-WDWJ7HC7.js} +182 -64
- package/dist/chunk-WDWJ7HC7.js.map +1 -0
- package/dist/{cli-4FCRBWED.js → cli-OITEPXW4.js} +2 -2
- package/dist/index.cjs +181 -63
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-K6ATAKGR.js.map +0 -1
- /package/dist/{cli-4FCRBWED.js.map → cli-OITEPXW4.js.map} +0 -0
package/dist/bin.cjs
CHANGED
|
@@ -11649,7 +11649,8 @@ Usage:
|
|
|
11649
11649
|
odla-ai pm bug list [--app <id>] [--status <s>] [--severity <s>] [--goal <id>] [--assignee <id>] [--decision <id>] [--q <text>] [--limit <n>] [--offset <n>] [--json]
|
|
11650
11650
|
odla-ai pm goal add --app <id> --title <t> [--status <s>] [--proof <text>] [--target <pct>] [--mutation-id <id>] [--json]
|
|
11651
11651
|
odla-ai pm task add --app <id> --title <t> [--column <backlog|ready|doing|review|done>] [--goal <id>|--alignment-decision <id>] [--assignee <id>] [--description <text>|--body <text>] [--acceptance <text>] [--execution <human|agent|either>] [--due <epoch-ms>] [--mutation-id <id>] [--json]
|
|
11652
|
-
odla-ai pm next --app <id> [--project <id>] [--json]
|
|
11652
|
+
odla-ai pm next --app <id> [--project <id>] [--verbose] [--json]
|
|
11653
|
+
odla-ai pm start --app <id> [<task-id>] [--goal <id>] [--verbose] [--mutation-id <id>] [--json] [claims the top Ready task in one call]
|
|
11653
11654
|
odla-ai pm watch --app <id> [--cursor <cursor>] [--entity goal|task|decision|bug] [--action created|updated|deleted|comment.created|comment.updated] [--state <state>] [--by <principalId>] [--self <principalId>] [--interval <s>] [--timeout <s>] [--json|--jsonl]
|
|
11654
11655
|
odla-ai pm task ready <id> --expected-revision <n> [--goal <id>|--alignment-decision <id>] [--description <text>|--body <text>] [--acceptance <text>] [--execution <human|agent|either>] [--mutation-id <id>] [--json]
|
|
11655
11656
|
odla-ai pm task claim <id> --expected-revision <n> [--mutation-id <id>] [--json]
|
|
@@ -11670,7 +11671,7 @@ Usage:
|
|
|
11670
11671
|
odla-ai pm <goal|task|decision|bug> comments <id> [--json]
|
|
11671
11672
|
odla-ai pm <goal|task|decision|bug> history <id> [--limit <n>] [--json]
|
|
11672
11673
|
odla-ai pm <goal|task|decision|bug> rm <id>
|
|
11673
|
-
odla-ai pm handoff --app <id> [--project <id>] [--json]
|
|
11674
|
+
odla-ai pm handoff --app <id> [--project <id>] [--verbose] [--json]
|
|
11674
11675
|
odla-ai discuss groups [--json]
|
|
11675
11676
|
odla-ai discuss list [--app <id>] [--q <text>] [--state open|resolved|all] [--mentions] [--json]
|
|
11676
11677
|
odla-ai discuss read <topic> [--limit <n> --offset <n>] [--json]
|
|
@@ -11837,6 +11838,16 @@ Commands:
|
|
|
11837
11838
|
execution contract and a reviewed revision. Any caller with PM
|
|
11838
11839
|
mutation access to that app/project may do it; claims coordinate
|
|
11839
11840
|
execution but never own or lock the PM record.
|
|
11841
|
+
To pick up work: "pm next" reads open goals, Ready candidates,
|
|
11842
|
+
and work in progress; "pm start" claims the top Ready task in
|
|
11843
|
+
one call, compare-and-swapped on the revision it just read, and
|
|
11844
|
+
returns the task, its goal, and the acceptance criteria to work
|
|
11845
|
+
against. Finish with "pm task done <id>", or hand it back with
|
|
11846
|
+
"pm task release <id> --expected-revision <n>". "pm start" never
|
|
11847
|
+
marks work Ready: that contract is reviewed separately so an
|
|
11848
|
+
agent cannot authorize its own work.
|
|
11849
|
+
Intake output is projected to the fields an executing caller
|
|
11850
|
+
acts on; --verbose returns whole records with their audit trail.
|
|
11840
11851
|
bug Intent-first alias for PM bugs. "bug report" writes to
|
|
11841
11852
|
odla PM; odla product defects do not belong in GitHub Issues.
|
|
11842
11853
|
discuss Group discussions (via @odla-ai/chat) for the apps you co-own:
|
|
@@ -12648,7 +12659,8 @@ async function pmRequest(ctx, method, path, body) {
|
|
|
12648
12659
|
const message2 = error.message;
|
|
12649
12660
|
if (typeof message2 === "string" && message2.length > 0) detail = message2;
|
|
12650
12661
|
}
|
|
12651
|
-
throw new
|
|
12662
|
+
throw new PmRequestError(
|
|
12663
|
+
response2.status,
|
|
12652
12664
|
`pm ${method} ${path} failed: ${detail ?? `registry returned ${response2.status}`} (${response2.status})`
|
|
12653
12665
|
);
|
|
12654
12666
|
}
|
|
@@ -12708,7 +12720,7 @@ function emit2(ctx, value2, human) {
|
|
|
12708
12720
|
if (ctx.json) ctx.out.log(JSON.stringify(value2, null, 2));
|
|
12709
12721
|
else human();
|
|
12710
12722
|
}
|
|
12711
|
-
var DONE, writeMutationId2, FIELD_MAP, STUDIO_SECTION;
|
|
12723
|
+
var DONE, writeMutationId2, FIELD_MAP, PmRequestError, isRevisionConflict, STUDIO_SECTION;
|
|
12712
12724
|
var init_pm_action_core = __esm({
|
|
12713
12725
|
"src/pm-action-core.ts"() {
|
|
12714
12726
|
"use strict";
|
|
@@ -12741,6 +12753,15 @@ var init_pm_action_core = __esm({
|
|
|
12741
12753
|
execution: { key: "executionMode" },
|
|
12742
12754
|
"expected-revision": { key: "expectedRevision", num: true }
|
|
12743
12755
|
};
|
|
12756
|
+
PmRequestError = class extends Error {
|
|
12757
|
+
constructor(status, message2) {
|
|
12758
|
+
super(message2);
|
|
12759
|
+
this.status = status;
|
|
12760
|
+
this.name = "PmRequestError";
|
|
12761
|
+
}
|
|
12762
|
+
status;
|
|
12763
|
+
};
|
|
12764
|
+
isRevisionConflict = (error) => error instanceof PmRequestError && error.status === 409;
|
|
12744
12765
|
STUDIO_SECTION = {
|
|
12745
12766
|
goal: "goals",
|
|
12746
12767
|
task: "board",
|
|
@@ -12872,110 +12893,231 @@ async function pmTaskLifecycle(ctx, id2, action2, parsed) {
|
|
|
12872
12893
|
ctx.out.log(`task: ${label} \u2192 ${state2}`);
|
|
12873
12894
|
});
|
|
12874
12895
|
}
|
|
12875
|
-
async function
|
|
12896
|
+
async function pmRemove(ctx, entity, id2) {
|
|
12897
|
+
await pmRequest(ctx, "DELETE", `/${entity}/${encodeURIComponent(id2)}`);
|
|
12898
|
+
ctx.out.log(`deleted ${entity} ${id2}`);
|
|
12899
|
+
}
|
|
12900
|
+
var init_pm_actions = __esm({
|
|
12901
|
+
"src/pm-actions.ts"() {
|
|
12902
|
+
"use strict";
|
|
12903
|
+
init_cjs_shims();
|
|
12904
|
+
init_argv();
|
|
12905
|
+
init_pm_action_core();
|
|
12906
|
+
}
|
|
12907
|
+
});
|
|
12908
|
+
|
|
12909
|
+
// src/pm-lean.ts
|
|
12910
|
+
function leanRecord(entity, record11) {
|
|
12911
|
+
const out = {};
|
|
12912
|
+
for (const key of [...COMMON, ...PER_ENTITY[entity]]) {
|
|
12913
|
+
const value2 = record11[key];
|
|
12914
|
+
if (value2 !== void 0 && value2 !== null) out[key] = value2;
|
|
12915
|
+
}
|
|
12916
|
+
return out;
|
|
12917
|
+
}
|
|
12918
|
+
function leanRecords(entity, records, verbose) {
|
|
12919
|
+
return verbose ? records : records.map((record11) => leanRecord(entity, record11));
|
|
12920
|
+
}
|
|
12921
|
+
var COMMON, PER_ENTITY;
|
|
12922
|
+
var init_pm_lean = __esm({
|
|
12923
|
+
"src/pm-lean.ts"() {
|
|
12924
|
+
"use strict";
|
|
12925
|
+
init_cjs_shims();
|
|
12926
|
+
COMMON = ["id", "appId", "projectId", "title", "revision"];
|
|
12927
|
+
PER_ENTITY = {
|
|
12928
|
+
goal: ["status", "proof", "targetPct", "currentPct"],
|
|
12929
|
+
task: [
|
|
12930
|
+
"column",
|
|
12931
|
+
"goalId",
|
|
12932
|
+
"alignmentDecisionId",
|
|
12933
|
+
"description",
|
|
12934
|
+
"acceptanceCriteria",
|
|
12935
|
+
"executionMode",
|
|
12936
|
+
"assigneeId",
|
|
12937
|
+
"claimedByPrincipalId",
|
|
12938
|
+
"dueAt"
|
|
12939
|
+
],
|
|
12940
|
+
decision: ["status", "body", "supersedesId"],
|
|
12941
|
+
bug: ["status", "severity", "description", "goalId", "assigneeId", "decisionId"]
|
|
12942
|
+
};
|
|
12943
|
+
}
|
|
12944
|
+
});
|
|
12945
|
+
|
|
12946
|
+
// src/pm-intake.ts
|
|
12947
|
+
async function listFiltered(ctx, entity, appId, projectId, filters) {
|
|
12876
12948
|
const records = [];
|
|
12877
12949
|
for (; ; ) {
|
|
12878
|
-
const q = new URLSearchParams({
|
|
12879
|
-
app: appId,
|
|
12880
|
-
limit: "100",
|
|
12881
|
-
offset: String(records.length)
|
|
12882
|
-
});
|
|
12950
|
+
const q = new URLSearchParams({ app: appId, limit: "100", offset: String(records.length) });
|
|
12883
12951
|
if (projectId) q.set("project", projectId);
|
|
12952
|
+
for (const [key, value2] of Object.entries(filters)) q.set(key, value2);
|
|
12884
12953
|
const page2 = await pmRequest(ctx, "GET", `/${entity}?${q}`);
|
|
12885
12954
|
records.push(...page2.records);
|
|
12886
12955
|
if (records.length >= page2.total || page2.records.length === 0) return records;
|
|
12887
12956
|
}
|
|
12888
12957
|
}
|
|
12889
|
-
|
|
12958
|
+
function requireApp(ctx, parsed, command) {
|
|
12890
12959
|
const appId = stringOpt(parsed.options.app) ?? ctx.appId;
|
|
12891
|
-
|
|
12892
|
-
|
|
12960
|
+
if (!appId) throw new Error(`pm ${command} needs --app <appId>`);
|
|
12961
|
+
return { appId, projectId: stringOpt(parsed.options.project) ?? ctx.projectId };
|
|
12962
|
+
}
|
|
12963
|
+
async function pmNext(ctx, parsed) {
|
|
12964
|
+
const { appId, projectId } = requireApp(ctx, parsed, "next");
|
|
12965
|
+
const verbose = wantsVerbose(parsed);
|
|
12893
12966
|
const [goals, tasks] = await Promise.all([
|
|
12894
|
-
|
|
12895
|
-
|
|
12967
|
+
listFiltered(ctx, "goal", appId, projectId, { status: UNMET_GOAL_STATUS }),
|
|
12968
|
+
// One request for both live columns; the split below is over open work only.
|
|
12969
|
+
listFiltered(ctx, "task", appId, projectId, { column: `${READY_COLUMN},doing` })
|
|
12896
12970
|
]);
|
|
12971
|
+
const ready = tasks.filter((record11) => record11.column === READY_COLUMN);
|
|
12972
|
+
const doing = tasks.filter((record11) => record11.column === "doing");
|
|
12973
|
+
const guidance = !goals.length ? "discuss alignment with the user before creating or claiming project work" : !ready.length ? 'refine a linked Backlog task and mark it Ready with "pm task ready <id>"' : `claim the top Ready task in one call: odla-ai pm start --app ${appId}`;
|
|
12897
12974
|
const result = {
|
|
12898
12975
|
appId,
|
|
12899
12976
|
projectId,
|
|
12900
|
-
openGoals:
|
|
12901
|
-
doing:
|
|
12902
|
-
ready:
|
|
12977
|
+
openGoals: leanRecords("goal", goals, verbose),
|
|
12978
|
+
doing: leanRecords("task", doing, verbose),
|
|
12979
|
+
ready: leanRecords("task", ready, verbose),
|
|
12980
|
+
next: guidance
|
|
12903
12981
|
};
|
|
12904
12982
|
emit2(ctx, result, () => {
|
|
12905
12983
|
ctx.out.log(`${appId}: goal-aligned work intake (read only)`);
|
|
12906
|
-
for (const [label, records] of [
|
|
12907
|
-
["doing",
|
|
12908
|
-
["ready",
|
|
12909
|
-
["open goals",
|
|
12984
|
+
for (const [label, entity, records] of [
|
|
12985
|
+
["doing", "task", doing],
|
|
12986
|
+
["ready", "task", ready],
|
|
12987
|
+
["open goals", "goal", goals]
|
|
12910
12988
|
]) {
|
|
12911
12989
|
ctx.out.log(`${label}:`);
|
|
12912
12990
|
if (!records.length) ctx.out.log("- (none)");
|
|
12913
|
-
else for (const record11 of records) printRecord(
|
|
12914
|
-
ctx,
|
|
12915
|
-
label === "open goals" ? "goal" : "task",
|
|
12916
|
-
record11
|
|
12917
|
-
);
|
|
12918
|
-
}
|
|
12919
|
-
if (!result.openGoals.length) {
|
|
12920
|
-
ctx.out.log("next: discuss alignment with the user before creating or claiming project work");
|
|
12921
|
-
} else if (!result.ready.length) {
|
|
12922
|
-
ctx.out.log("next: refine a linked Backlog task and mark it Ready");
|
|
12923
|
-
} else {
|
|
12924
|
-
ctx.out.log("next: review a Ready task, then claim it with its revision");
|
|
12991
|
+
else for (const record11 of records) printRecord(ctx, entity, record11);
|
|
12925
12992
|
}
|
|
12993
|
+
ctx.out.log(`next: ${guidance}`);
|
|
12926
12994
|
});
|
|
12927
12995
|
}
|
|
12928
12996
|
async function pmHandoff(ctx, parsed) {
|
|
12929
|
-
const appId =
|
|
12930
|
-
const
|
|
12931
|
-
if (!appId) throw new Error("pm handoff needs --app <appId>");
|
|
12997
|
+
const { appId, projectId } = requireApp(ctx, parsed, "handoff");
|
|
12998
|
+
const verbose = wantsVerbose(parsed);
|
|
12932
12999
|
const [goals, tasks, bugs] = await Promise.all([
|
|
12933
|
-
|
|
12934
|
-
|
|
12935
|
-
|
|
13000
|
+
listFiltered(ctx, "goal", appId, projectId, { status: UNMET_GOAL_STATUS }),
|
|
13001
|
+
listFiltered(ctx, "task", appId, projectId, { column: ACTIVE_TASK_COLUMNS }),
|
|
13002
|
+
listFiltered(ctx, "bug", appId, projectId, { status: OPEN_BUG_STATUSES })
|
|
12936
13003
|
]);
|
|
12937
|
-
const
|
|
13004
|
+
const clean4 = !goals.length && !tasks.length && !bugs.length;
|
|
13005
|
+
const result = {
|
|
12938
13006
|
appId,
|
|
12939
13007
|
projectId,
|
|
12940
|
-
unmetGoals:
|
|
12941
|
-
activeTasks:
|
|
12942
|
-
openBugs:
|
|
12943
|
-
|
|
12944
|
-
const result = {
|
|
12945
|
-
...handoff,
|
|
12946
|
-
clean: !handoff.unmetGoals.length && !handoff.activeTasks.length && !handoff.openBugs.length
|
|
13008
|
+
unmetGoals: leanRecords("goal", goals, verbose),
|
|
13009
|
+
activeTasks: leanRecords("task", tasks, verbose),
|
|
13010
|
+
openBugs: leanRecords("bug", bugs, verbose),
|
|
13011
|
+
clean: clean4
|
|
12947
13012
|
};
|
|
12948
13013
|
emit2(ctx, result, () => {
|
|
12949
|
-
if (
|
|
13014
|
+
if (clean4) {
|
|
12950
13015
|
ctx.out.log(`${appId}: no unresolved PM work`);
|
|
12951
13016
|
return;
|
|
12952
13017
|
}
|
|
12953
13018
|
ctx.out.log(`${appId}: authoritative PM handoff`);
|
|
12954
|
-
for (const [label, records] of [
|
|
12955
|
-
["unmet goals",
|
|
12956
|
-
["active tasks",
|
|
12957
|
-
["open bugs",
|
|
13019
|
+
for (const [label, entity, records] of [
|
|
13020
|
+
["unmet goals", "goal", goals],
|
|
13021
|
+
["active tasks", "task", tasks],
|
|
13022
|
+
["open bugs", "bug", bugs]
|
|
12958
13023
|
]) {
|
|
12959
13024
|
ctx.out.log(`${label}:`);
|
|
12960
13025
|
if (!records.length) ctx.out.log("- (none)");
|
|
12961
|
-
else for (const record11 of records) printRecord(
|
|
12962
|
-
ctx,
|
|
12963
|
-
label === "unmet goals" ? "goal" : label === "active tasks" ? "task" : "bug",
|
|
12964
|
-
record11
|
|
12965
|
-
);
|
|
13026
|
+
else for (const record11 of records) printRecord(ctx, entity, record11);
|
|
12966
13027
|
}
|
|
12967
13028
|
});
|
|
12968
13029
|
}
|
|
12969
|
-
|
|
12970
|
-
|
|
12971
|
-
|
|
13030
|
+
var READY_COLUMN, UNMET_GOAL_STATUS, ACTIVE_TASK_COLUMNS, OPEN_BUG_STATUSES, wantsVerbose;
|
|
13031
|
+
var init_pm_intake = __esm({
|
|
13032
|
+
"src/pm-intake.ts"() {
|
|
13033
|
+
"use strict";
|
|
13034
|
+
init_cjs_shims();
|
|
13035
|
+
init_argv();
|
|
13036
|
+
init_pm_action_core();
|
|
13037
|
+
init_pm_lean();
|
|
13038
|
+
READY_COLUMN = "todo";
|
|
13039
|
+
UNMET_GOAL_STATUS = "open";
|
|
13040
|
+
ACTIVE_TASK_COLUMNS = "backlog,todo,doing,review";
|
|
13041
|
+
OPEN_BUG_STATUSES = "open,triaged";
|
|
13042
|
+
wantsVerbose = (parsed) => parsed.options.verbose === true;
|
|
13043
|
+
}
|
|
13044
|
+
});
|
|
13045
|
+
|
|
13046
|
+
// src/pm-start.ts
|
|
13047
|
+
async function claimAt(ctx, task, parsed) {
|
|
13048
|
+
const res = await pmRequest(
|
|
13049
|
+
ctx,
|
|
13050
|
+
"POST",
|
|
13051
|
+
`/task/${encodeURIComponent(task.id)}/claim`,
|
|
13052
|
+
{ expectedRevision: task.revision, mutationId: writeMutationId2(parsed) }
|
|
13053
|
+
);
|
|
13054
|
+
return res.record;
|
|
13055
|
+
}
|
|
13056
|
+
async function selectTask(ctx, parsed, appId, projectId) {
|
|
13057
|
+
const named = parsed.positionals[2];
|
|
13058
|
+
if (named) return getTask(ctx, named);
|
|
13059
|
+
const goalId = stringOpt(parsed.options.goal);
|
|
13060
|
+
const ready = await listFiltered(ctx, "task", appId, projectId, {
|
|
13061
|
+
column: READY_COLUMN,
|
|
13062
|
+
...goalId ? { goalId } : {}
|
|
13063
|
+
});
|
|
13064
|
+
const candidate = ready[0];
|
|
13065
|
+
if (!candidate) {
|
|
13066
|
+
throw new Error(
|
|
13067
|
+
`no Ready task to claim in ${appId}${goalId ? ` for goal ${goalId}` : ""}. Run "odla-ai pm next --app ${appId}" to see open goals and Backlog work, then "odla-ai pm task ready <id>" once a task has a complete contract.`
|
|
13068
|
+
);
|
|
13069
|
+
}
|
|
13070
|
+
return candidate;
|
|
12972
13071
|
}
|
|
12973
|
-
|
|
12974
|
-
|
|
13072
|
+
async function pmStart(ctx, parsed) {
|
|
13073
|
+
const appId = stringOpt(parsed.options.app) ?? ctx.appId;
|
|
13074
|
+
if (!appId) throw new Error("pm start needs --app <appId>");
|
|
13075
|
+
const projectId = stringOpt(parsed.options.project) ?? ctx.projectId;
|
|
13076
|
+
const verbose = wantsVerbose(parsed);
|
|
13077
|
+
const selected = await selectTask(ctx, parsed, appId, projectId);
|
|
13078
|
+
if (selected.column !== READY_COLUMN) {
|
|
13079
|
+
throw new Error(
|
|
13080
|
+
`task ${selected.id} is ${selected.column === "doing" ? "already claimed" : `in ${selected.column}`}, not Ready. Only Ready work can be started; run "odla-ai pm task ready ${selected.id} --expected-revision ${selected.revision}" once its goal, description, and acceptance criteria are complete.`
|
|
13081
|
+
);
|
|
13082
|
+
}
|
|
13083
|
+
let claimed;
|
|
13084
|
+
try {
|
|
13085
|
+
claimed = await claimAt(ctx, selected, parsed);
|
|
13086
|
+
} catch (error) {
|
|
13087
|
+
if (!isRevisionConflict(error)) throw error;
|
|
13088
|
+
const reloaded = await getTask(ctx, selected.id);
|
|
13089
|
+
if (reloaded.column !== READY_COLUMN) {
|
|
13090
|
+
throw new Error(
|
|
13091
|
+
`task ${selected.id} was taken while starting it (now ${reloaded.column}). Run "odla-ai pm start --app ${appId}" again to take the next Ready task.`
|
|
13092
|
+
);
|
|
13093
|
+
}
|
|
13094
|
+
claimed = await claimAt(ctx, reloaded, parsed);
|
|
13095
|
+
}
|
|
13096
|
+
const task = claimed ?? await getTask(ctx, selected.id);
|
|
13097
|
+
const goalId = typeof task.goalId === "string" ? task.goalId : void 0;
|
|
13098
|
+
const goal = goalId ? await pmRequest(ctx, "GET", `/goal/${encodeURIComponent(goalId)}`).then((res) => res.record).catch(() => null) : null;
|
|
13099
|
+
const result = {
|
|
13100
|
+
claimed: verbose ? task : leanRecord("task", task),
|
|
13101
|
+
goal: goal ? verbose ? goal : leanRecord("goal", goal) : null,
|
|
13102
|
+
next: 'work the acceptance criteria, then "odla-ai pm task done <id>" (or "odla-ai pm task release <id> --expected-revision <n>" to hand it back)'
|
|
13103
|
+
};
|
|
13104
|
+
emit2(ctx, result, () => {
|
|
13105
|
+
ctx.out.log(`claimed: ${studioRecordLink(ctx, "task", task)}`);
|
|
13106
|
+
if (goal) ctx.out.log(`goal: ${studioRecordLink(ctx, "goal", goal)}`);
|
|
13107
|
+
if (typeof task.acceptanceCriteria === "string") ctx.out.log(`acceptance: ${task.acceptanceCriteria}`);
|
|
13108
|
+
ctx.out.log(`next: ${result.next}`);
|
|
13109
|
+
});
|
|
13110
|
+
}
|
|
13111
|
+
var getTask;
|
|
13112
|
+
var init_pm_start = __esm({
|
|
13113
|
+
"src/pm-start.ts"() {
|
|
12975
13114
|
"use strict";
|
|
12976
13115
|
init_cjs_shims();
|
|
12977
13116
|
init_argv();
|
|
12978
13117
|
init_pm_action_core();
|
|
13118
|
+
init_pm_lean();
|
|
13119
|
+
init_pm_intake();
|
|
13120
|
+
getTask = async (ctx, id2) => (await pmRequest(ctx, "GET", `/task/${encodeURIComponent(id2)}`)).record;
|
|
12979
13121
|
}
|
|
12980
13122
|
});
|
|
12981
13123
|
|
|
@@ -13457,9 +13599,13 @@ async function pmCommand(parsed, deps = {}) {
|
|
|
13457
13599
|
throw new Error(`unknown pm project action "${action3}". Try list|add|use.`);
|
|
13458
13600
|
}
|
|
13459
13601
|
if (word === "next") {
|
|
13460
|
-
assertArgs(parsed, [...COMMON_OPTIONS, "app", "project"], 2);
|
|
13602
|
+
assertArgs(parsed, [...COMMON_OPTIONS, "app", "project", "verbose"], 2);
|
|
13461
13603
|
return pmNext(await buildContext2(parsed, deps), parsed);
|
|
13462
13604
|
}
|
|
13605
|
+
if (word === "start") {
|
|
13606
|
+
assertArgs(parsed, [...COMMON_OPTIONS, "app", "project", "goal", "verbose", "mutation-id"], 3);
|
|
13607
|
+
return pmStart(await buildContext2(parsed, deps), parsed);
|
|
13608
|
+
}
|
|
13463
13609
|
if (word === "watch") {
|
|
13464
13610
|
assertArgs(parsed, [
|
|
13465
13611
|
...COMMON_OPTIONS,
|
|
@@ -13477,11 +13623,11 @@ async function pmCommand(parsed, deps = {}) {
|
|
|
13477
13623
|
return pmWatch(await buildContext2(parsed, deps), parsed).then(() => void 0);
|
|
13478
13624
|
}
|
|
13479
13625
|
if (word === "handoff") {
|
|
13480
|
-
assertArgs(parsed, [...COMMON_OPTIONS, "app", "project"], 2);
|
|
13626
|
+
assertArgs(parsed, [...COMMON_OPTIONS, "app", "project", "verbose"], 2);
|
|
13481
13627
|
return pmHandoff(await buildContext2(parsed, deps), parsed);
|
|
13482
13628
|
}
|
|
13483
13629
|
const entity = ALIASES[word];
|
|
13484
|
-
if (!entity) throw new Error(`unknown pm entity "${word}". Try "odla-ai pm bug list" (goal|task|decision|bug).`);
|
|
13630
|
+
if (!entity) throw new Error(`unknown pm entity "${word}". Try "odla-ai pm start" to claim Ready work, or "odla-ai pm bug list" (goal|task|decision|bug).`);
|
|
13485
13631
|
const requestedAction = parsed.positionals[2] ?? "list";
|
|
13486
13632
|
const action2 = canonicalAction(requestedAction);
|
|
13487
13633
|
if (!action2) throw new Error(`unknown pm action "${requestedAction}". Try list|add|get|set|done|link|ref|comment|comments|history|rm.`);
|
|
@@ -13528,6 +13674,8 @@ var init_pm_command = __esm({
|
|
|
13528
13674
|
init_argv();
|
|
13529
13675
|
init_operator_context();
|
|
13530
13676
|
init_pm_actions();
|
|
13677
|
+
init_pm_intake();
|
|
13678
|
+
init_pm_start();
|
|
13531
13679
|
init_pm_links();
|
|
13532
13680
|
init_pm_comments();
|
|
13533
13681
|
init_pm_history();
|