@hasna/todos 0.15.51 → 0.16.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/CHANGELOG.md +1884 -0
- package/README.md +314 -37
- package/dist/ai-tools.d.ts.map +1 -1
- package/dist/ai.d.ts.map +1 -1
- package/dist/cli/cloud-router.d.ts +99 -51
- package/dist/cli/cloud-router.d.ts.map +1 -1
- package/dist/cli/commands/agent-commands.d.ts.map +1 -1
- package/dist/cli/commands/config-serve-commands.d.ts.map +1 -1
- package/dist/cli/commands/delegate.d.ts.map +1 -1
- package/dist/cli/commands/environment-snapshots.d.ts.map +1 -1
- package/dist/cli/commands/machines-api.d.ts +4 -0
- package/dist/cli/commands/machines-api.d.ts.map +1 -0
- package/dist/cli/commands/machines.d.ts.map +1 -1
- package/dist/cli/commands/mcp-hooks-commands.d.ts.map +1 -1
- package/dist/cli/commands/plan-commands.d.ts +3 -0
- package/dist/cli/commands/plan-commands.d.ts.map +1 -0
- package/dist/cli/commands/plan-template-commands.d.ts.map +1 -1
- package/dist/cli/commands/pr-group-commands.d.ts.map +1 -1
- package/dist/cli/commands/project-commands.d.ts +15 -0
- package/dist/cli/commands/project-commands.d.ts.map +1 -1
- package/dist/cli/commands/query-commands.d.ts.map +1 -1
- package/dist/cli/commands/storage-commands.d.ts.map +1 -1
- package/dist/cli/commands/task-list-commands.d.ts +3 -0
- package/dist/cli/commands/task-list-commands.d.ts.map +1 -0
- package/dist/cli/commands/template-commands.d.ts +3 -0
- package/dist/cli/commands/template-commands.d.ts.map +1 -0
- package/dist/cli/helpers.d.ts.map +1 -1
- package/dist/cli/index.js +15156 -11088
- package/dist/cli/machine-api.d.ts +7 -0
- package/dist/cli/machine-api.d.ts.map +1 -0
- package/dist/cli/plan-read-api.d.ts +6 -0
- package/dist/cli/plan-read-api.d.ts.map +1 -0
- package/dist/cli/project-api.d.ts +119 -0
- package/dist/cli/project-api.d.ts.map +1 -0
- package/dist/cli/stage-a.d.ts +34 -4
- package/dist/cli/stage-a.d.ts.map +1 -1
- package/dist/cli/task-query-api.d.ts +21 -0
- package/dist/cli/task-query-api.d.ts.map +1 -0
- package/dist/cli/template-api.d.ts +7 -0
- package/dist/cli/template-api.d.ts.map +1 -0
- package/dist/contracts.js +836 -266
- package/dist/db/builtin-templates.d.ts +2 -33
- package/dist/db/builtin-templates.d.ts.map +1 -1
- package/dist/db/database.d.ts.map +1 -1
- package/dist/db/handoffs.d.ts.map +1 -1
- package/dist/db/machines.d.ts.map +1 -1
- package/dist/db/migrations.d.ts.map +1 -1
- package/dist/db/plans.d.ts.map +1 -1
- package/dist/db/retrospectives.d.ts.map +1 -1
- package/dist/db/schema.d.ts.map +1 -1
- package/dist/db/task-lists.d.ts.map +1 -1
- package/dist/db/task-runs.d.ts +2 -0
- package/dist/db/task-runs.d.ts.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3863 -1708
- package/dist/lib/assignee-validation.d.ts.map +1 -1
- package/dist/lib/builtin-template-library.d.ts +32 -0
- package/dist/lib/builtin-template-library.d.ts.map +1 -0
- package/dist/lib/cli-reference.d.ts.map +1 -1
- package/dist/lib/config.d.ts +10 -13
- package/dist/lib/config.d.ts.map +1 -1
- package/dist/lib/db-backup.d.ts +1 -1
- package/dist/lib/db-backup.d.ts.map +1 -1
- package/dist/lib/env.d.ts +18 -0
- package/dist/lib/env.d.ts.map +1 -0
- package/dist/lib/environment-snapshots.d.ts.map +1 -1
- package/dist/lib/gatherer.d.ts.map +1 -1
- package/dist/lib/headless-boundaries.d.ts +4 -3
- package/dist/lib/headless-boundaries.d.ts.map +1 -1
- package/dist/lib/local-encryption.d.ts +12 -0
- package/dist/lib/local-encryption.d.ts.map +1 -1
- package/dist/lib/local-opt-in.d.ts +90 -0
- package/dist/lib/local-opt-in.d.ts.map +1 -0
- package/dist/lib/paths.d.ts +9 -0
- package/dist/lib/paths.d.ts.map +1 -1
- package/dist/lib/plan-artifacts.d.ts +1 -0
- package/dist/lib/plan-artifacts.d.ts.map +1 -1
- package/dist/lib/plan-client-boundary.d.ts +2 -0
- package/dist/lib/plan-client-boundary.d.ts.map +1 -0
- package/dist/lib/plan-schedule.d.ts +6 -0
- package/dist/lib/plan-schedule.d.ts.map +1 -0
- package/dist/lib/project-panel.d.ts +6 -0
- package/dist/lib/project-panel.d.ts.map +1 -1
- package/dist/lib/project-receipt.d.ts +3 -0
- package/dist/lib/project-receipt.d.ts.map +1 -0
- package/dist/lib/sandbox-profiles.d.ts.map +1 -1
- package/dist/lib/shared-plan-artifacts.d.ts +14 -0
- package/dist/lib/shared-plan-artifacts.d.ts.map +1 -0
- package/dist/lib/sync.d.ts.map +1 -1
- package/dist/lib/task-list-client-boundary.d.ts +3 -0
- package/dist/lib/task-list-client-boundary.d.ts.map +1 -0
- package/dist/lib/task-routing.d.ts.map +1 -1
- package/dist/lib/template-client-boundary.d.ts +2 -0
- package/dist/lib/template-client-boundary.d.ts.map +1 -0
- package/dist/mcp/index.d.ts +1 -0
- package/dist/mcp/index.d.ts.map +1 -1
- package/dist/mcp/index.js +45195 -40368
- package/dist/mcp/plan-api.d.ts +6 -0
- package/dist/mcp/plan-api.d.ts.map +1 -0
- package/dist/mcp/remote-authority.d.ts +49 -0
- package/dist/mcp/remote-authority.d.ts.map +1 -0
- package/dist/mcp/task-coordination-api.d.ts +15 -0
- package/dist/mcp/task-coordination-api.d.ts.map +1 -0
- package/dist/mcp/task-list-api.d.ts +8 -0
- package/dist/mcp/task-list-api.d.ts.map +1 -0
- package/dist/mcp/token-utils.d.ts.map +1 -1
- package/dist/mcp/tools/environment-snapshots.d.ts.map +1 -1
- package/dist/mcp/tools/machines.d.ts.map +1 -1
- package/dist/mcp/tools/task-project-tools.d.ts.map +1 -1
- package/dist/mcp/tools/task-resources.d.ts.map +1 -1
- package/dist/mcp.d.ts +2 -2
- package/dist/mcp.d.ts.map +1 -1
- package/dist/mcp.js +45 -19
- package/dist/project-registration.js +2830 -557
- package/dist/registry.js +837 -267
- package/dist/release-provenance.json +6 -6
- package/dist/sdk/client.d.ts +51 -4
- package/dist/sdk/client.d.ts.map +1 -1
- package/dist/sdk/index.d.ts +2 -0
- package/dist/sdk/index.d.ts.map +1 -1
- package/dist/sdk/index.js +1209 -1080
- package/dist/sdk/resolve.d.ts +91 -0
- package/dist/sdk/resolve.d.ts.map +1 -0
- package/dist/sdk/v1.generated.d.ts +219 -3
- package/dist/sdk/v1.generated.d.ts.map +1 -1
- package/dist/server/auth-posture.d.ts +66 -7
- package/dist/server/auth-posture.d.ts.map +1 -1
- package/dist/server/client-ip.d.ts +39 -0
- package/dist/server/client-ip.d.ts.map +1 -0
- package/dist/server/cloud.d.ts +2 -1
- package/dist/server/cloud.d.ts.map +1 -1
- package/dist/server/index.d.ts +1 -1
- package/dist/server/index.js +20556 -15533
- package/dist/server/openapi.d.ts +1341 -83
- package/dist/server/openapi.d.ts.map +1 -1
- package/dist/server/port.d.ts +2 -2
- package/dist/server/port.d.ts.map +1 -1
- package/dist/server/routes.d.ts +3 -6
- package/dist/server/routes.d.ts.map +1 -1
- package/dist/server/serve.d.ts +2 -6
- package/dist/server/serve.d.ts.map +1 -1
- package/dist/server/v1.d.ts +3 -1
- package/dist/server/v1.d.ts.map +1 -1
- package/dist/storage/atomic-project-migration.d.ts +53 -0
- package/dist/storage/atomic-project-migration.d.ts.map +1 -0
- package/dist/storage/index.d.ts +3 -1
- package/dist/storage/index.d.ts.map +1 -1
- package/dist/storage/interfaces.d.ts +61 -0
- package/dist/storage/interfaces.d.ts.map +1 -1
- package/dist/storage/machine-registry.d.ts +36 -0
- package/dist/storage/machine-registry.d.ts.map +1 -0
- package/dist/storage/postgres-adapter.d.ts.map +1 -1
- package/dist/storage/postgres-sync.d.ts +2 -2
- package/dist/storage/postgres-sync.d.ts.map +1 -1
- package/dist/storage/run-artifact-creation-upload.d.ts +50 -0
- package/dist/storage/run-artifact-creation-upload.d.ts.map +1 -0
- package/dist/storage/s3-artifact-sync.d.ts +18 -0
- package/dist/storage/s3-artifact-sync.d.ts.map +1 -1
- package/dist/storage/sqlite-snapshot.d.ts +2 -0
- package/dist/storage/sqlite-snapshot.d.ts.map +1 -1
- package/dist/storage.d.ts +2 -2
- package/dist/storage.d.ts.map +1 -1
- package/dist/storage.js +2695 -322
- package/dist/task-manifest/postgres.d.ts +1 -1
- package/dist/task-manifest/sqlite.d.ts +1 -1
- package/dist/task-manifest.js +244 -73
- package/dist/task-subtree-transfer.js +198 -4
- package/dist/testing.d.ts +90 -29
- package/dist/testing.d.ts.map +1 -1
- package/dist/testing.js +34 -10
- package/dist/types/index.d.ts +40 -4
- package/dist/types/index.d.ts.map +1 -1
- package/docs/PLAN_API.md +93 -0
- package/docs/TASK_LIST_API.md +58 -0
- package/docs/TASK_QUERY_API.md +14 -0
- package/docs/TEMPLATE_API.md +18 -0
- package/docs/native-storage.md +405 -0
- package/package.json +19 -16
- package/postinstall.js +52 -1
- package/dashboard/dist/assets/index-BNQ4gJua.js +0 -342
- package/dashboard/dist/assets/index-DjzvHUWt.css +0 -1
- package/dashboard/dist/index.html +0 -13
- package/dashboard/dist/logo.jpg +0 -0
package/dist/sdk/index.js
CHANGED
|
@@ -52,1292 +52,1420 @@ class TodosTimeoutError extends Error {
|
|
|
52
52
|
}
|
|
53
53
|
}
|
|
54
54
|
|
|
55
|
-
// src/
|
|
56
|
-
import {
|
|
57
|
-
|
|
55
|
+
// src/sdk/resolve.ts
|
|
56
|
+
import {
|
|
57
|
+
ClientTransportConfigurationError,
|
|
58
|
+
resolveClientTransport,
|
|
59
|
+
resolveCredential
|
|
60
|
+
} from "@hasna/contracts/client";
|
|
58
61
|
|
|
59
|
-
// src/
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
// node_modules/.bun/@hasna+paths@0.1.0/node_modules/@hasna/paths/dist/index.js
|
|
69
|
-
import { homedir } from "os";
|
|
70
|
-
import { join } from "path";
|
|
71
|
-
var KIND_ENV = {
|
|
72
|
-
config: "HASNA_CONFIG_HOME",
|
|
73
|
-
data: "HASNA_DATA_HOME",
|
|
74
|
-
state: "HASNA_STATE_HOME",
|
|
75
|
-
cache: "HASNA_CACHE_HOME"
|
|
76
|
-
};
|
|
77
|
-
var APP_SLUG_RE = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
|
|
78
|
-
function assertApp(app) {
|
|
79
|
-
if (typeof app !== "string" || app.length === 0) {
|
|
80
|
-
throw new TypeError("paths: app must be a non-empty string");
|
|
81
|
-
}
|
|
82
|
-
if (!APP_SLUG_RE.test(app)) {
|
|
83
|
-
throw new TypeError(`paths: invalid app slug "${app}" \u2014 expected lowercase kebab-case ([a-z0-9]+(-[a-z0-9]+)*)`);
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
function envOf(options) {
|
|
87
|
-
return options.env ?? process.env;
|
|
88
|
-
}
|
|
89
|
-
function envValue(options, kind) {
|
|
90
|
-
const value = envOf(options)[KIND_ENV[kind]];
|
|
91
|
-
return typeof value === "string" && value.length > 0 ? value : undefined;
|
|
92
|
-
}
|
|
93
|
-
function isMacOS(platform) {
|
|
94
|
-
return platform === "darwin";
|
|
95
|
-
}
|
|
96
|
-
function baseDir(kind, options) {
|
|
97
|
-
const override = envValue(options, kind);
|
|
98
|
-
if (override)
|
|
99
|
-
return override;
|
|
100
|
-
const home = options.home ?? homedir();
|
|
101
|
-
const platform = options.platform ?? process.platform;
|
|
102
|
-
if (isMacOS(platform)) {
|
|
103
|
-
switch (kind) {
|
|
104
|
-
case "config":
|
|
105
|
-
case "data":
|
|
106
|
-
return join(home, "Library", "Application Support", "Hasna");
|
|
107
|
-
case "cache":
|
|
108
|
-
return join(home, "Library", "Caches", "Hasna");
|
|
109
|
-
case "state":
|
|
110
|
-
return join(home, "Library", "Logs", "Hasna");
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
switch (kind) {
|
|
114
|
-
case "config":
|
|
115
|
-
return join(home, ".config", "hasna");
|
|
116
|
-
case "data":
|
|
117
|
-
return join(home, ".local", "share", "hasna");
|
|
118
|
-
case "state":
|
|
119
|
-
return join(home, ".local", "state", "hasna");
|
|
120
|
-
case "cache":
|
|
121
|
-
return join(home, ".cache", "hasna");
|
|
62
|
+
// src/project-registration/types.ts
|
|
63
|
+
class TodosProjectRegistrationError extends Error {
|
|
64
|
+
code;
|
|
65
|
+
details;
|
|
66
|
+
constructor(code, message, details = {}) {
|
|
67
|
+
super(message);
|
|
68
|
+
this.code = code;
|
|
69
|
+
this.details = details;
|
|
70
|
+
this.name = "TodosProjectRegistrationError";
|
|
122
71
|
}
|
|
123
72
|
}
|
|
124
|
-
function resolvePath(kind, options) {
|
|
125
|
-
assertApp(options.app);
|
|
126
|
-
const appSegment = options.internal === true ? join("internal", options.app) : options.app;
|
|
127
|
-
return join(baseDir(kind, options), appSegment);
|
|
128
|
-
}
|
|
129
|
-
function dataDir(options) {
|
|
130
|
-
return resolvePath("data", options);
|
|
131
|
-
}
|
|
132
73
|
|
|
133
|
-
// src/
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
return existsSync(join2(resolved, "todos.db")) || existsSync(join2(resolved, "config.json"));
|
|
74
|
+
// src/project-registration/adoption-validation.ts
|
|
75
|
+
var VALIDATION_KEYS = [
|
|
76
|
+
"valid",
|
|
77
|
+
"resource_kind",
|
|
78
|
+
"target_id",
|
|
79
|
+
"source_receipt_id",
|
|
80
|
+
"accepted_receipt_id",
|
|
81
|
+
"source_outcome",
|
|
82
|
+
"created_at",
|
|
83
|
+
"current_revision",
|
|
84
|
+
"accepted_result_digest"
|
|
85
|
+
];
|
|
86
|
+
function isRecord(value) {
|
|
87
|
+
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
148
88
|
}
|
|
149
|
-
function
|
|
150
|
-
|
|
151
|
-
return resolve(adoptResolverHome(resolved, env) ? resolved : legacyHomeDir(env));
|
|
89
|
+
function isNonEmptyString(value) {
|
|
90
|
+
return typeof value === "string" && value.length > 0;
|
|
152
91
|
}
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
return
|
|
92
|
+
function hasExactKeys(value, expected) {
|
|
93
|
+
const actual = Object.keys(value).sort();
|
|
94
|
+
const wanted = [...expected].sort();
|
|
95
|
+
return actual.length === wanted.length && actual.every((key, index) => key === wanted[index]);
|
|
157
96
|
}
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
return getTodosDir();
|
|
97
|
+
function adoptionRejected(message) {
|
|
98
|
+
throw new TodosProjectRegistrationError("TODOS_PROJECT_REGISTRATION_ADOPTION_REJECTED", `TODOS_PROJECT_REGISTRATION_ADOPTION_REJECTED: ${message}`);
|
|
161
99
|
}
|
|
162
|
-
function
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
100
|
+
function assertTodosPriorRegistrationAdoptionValidationEnvelope(value, input) {
|
|
101
|
+
if (!isRecord(input) || !hasExactKeys(input, [
|
|
102
|
+
"source_request",
|
|
103
|
+
"source_receipt",
|
|
104
|
+
"current_record"
|
|
105
|
+
])) {
|
|
106
|
+
adoptionRejected("prior-adoption validation input is incomplete");
|
|
167
107
|
}
|
|
108
|
+
const request = input["source_request"];
|
|
109
|
+
const receipt = input["source_receipt"];
|
|
110
|
+
const current = input["current_record"];
|
|
111
|
+
if (!isRecord(request) || !isRecord(receipt) || !isRecord(current)) {
|
|
112
|
+
adoptionRejected("prior-adoption validation input records are incomplete");
|
|
113
|
+
}
|
|
114
|
+
const resourceKind = request["resource_kind"];
|
|
115
|
+
const sourceOutcome = receipt["outcome"];
|
|
116
|
+
const acceptedReceiptId = sourceOutcome === "accepted" ? receipt["receipt_id"] : sourceOutcome === "duplicate_of_accepted" ? receipt["duplicate_of_receipt_id"] : null;
|
|
117
|
+
if (resourceKind !== "project" && resourceKind !== "task_list" || request["direction"] !== "forward" || sourceOutcome !== "accepted" && sourceOutcome !== "duplicate_of_accepted" || !isNonEmptyString(acceptedReceiptId) || !isNonEmptyString(receipt["receipt_id"]) || !isNonEmptyString(receipt["target_id"]) || !isNonEmptyString(receipt["result_revision"]) || !isNonEmptyString(receipt["result_digest"]) || !isNonEmptyString(current["id"]) || !isNonEmptyString(current["created_at"]) || !isNonEmptyString(current["updated_at"]) || receipt["authority"] !== "todos" || receipt["route"] !== request["authority_route"] || receipt["package_version"] !== request["package_version"] || receipt["authority_id"] !== request["authority_id"] || receipt["tenant_id"] !== request["tenant_id"] || receipt["corpus_id"] !== request["corpus_id"] || receipt["operation_id"] !== request["operation_id"] || receipt["step_id"] !== request["step_id"] || receipt["resource_kind"] !== resourceKind || receipt["direction"] !== "forward" || receipt["idempotency_key"] !== request["idempotency_key"] || receipt["request_digest"] !== request["request_digest"] || receipt["precondition_digest"] !== request["precondition_digest"] || receipt["accepted_receipt_id"] !== null || receipt["target_id"] !== current["id"] || receipt["result_revision"] !== current["created_at"]) {
|
|
118
|
+
adoptionRejected("prior-adoption validation input does not carry one complete accepted receipt and current target incarnation");
|
|
119
|
+
}
|
|
120
|
+
if (sourceOutcome === "accepted" && receipt["duplicate_of_receipt_id"] !== null || sourceOutcome === "duplicate_of_accepted" && receipt["duplicate_of_receipt_id"] !== acceptedReceiptId) {
|
|
121
|
+
adoptionRejected("prior-adoption validation source receipt lineage is incomplete");
|
|
122
|
+
}
|
|
123
|
+
if (!isRecord(value) || !hasExactKeys(value, ["validation"]) || !isRecord(value["validation"]) || !hasExactKeys(value["validation"], VALIDATION_KEYS)) {
|
|
124
|
+
adoptionRejected("prior-adoption validation response envelope is incomplete");
|
|
125
|
+
}
|
|
126
|
+
const validation = value["validation"];
|
|
127
|
+
if (validation["valid"] !== true || validation["resource_kind"] !== resourceKind || validation["target_id"] !== current["id"] || validation["source_receipt_id"] !== receipt["receipt_id"] || validation["accepted_receipt_id"] !== acceptedReceiptId || validation["source_outcome"] !== sourceOutcome || validation["created_at"] !== current["created_at"] || validation["current_revision"] !== current["updated_at"] || validation["accepted_result_digest"] !== receipt["result_digest"]) {
|
|
128
|
+
adoptionRejected("prior-adoption validation response does not prove the exact accepted receipt and current target");
|
|
129
|
+
}
|
|
130
|
+
return validation;
|
|
168
131
|
}
|
|
169
132
|
|
|
170
|
-
// src/
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
cached = {};
|
|
180
|
-
return cached;
|
|
181
|
-
}
|
|
182
|
-
const config = readJsonFile(getConfigPath()) || {};
|
|
183
|
-
if (typeof config.sync_agents === "string") {
|
|
184
|
-
config.sync_agents = config.sync_agents.split(",").map((a) => a.trim()).filter(Boolean);
|
|
185
|
-
}
|
|
186
|
-
cached = config;
|
|
187
|
-
return cached;
|
|
188
|
-
}
|
|
189
|
-
function normalizeApiUrl(value) {
|
|
190
|
-
const trimmed = value?.trim();
|
|
191
|
-
if (!trimmed)
|
|
192
|
-
return null;
|
|
193
|
-
return trimmed.replace(/\/+$/, "");
|
|
194
|
-
}
|
|
195
|
-
function getLocalApiConfig(env = process.env) {
|
|
196
|
-
const config = loadConfig();
|
|
197
|
-
const envApiUrl = normalizeApiUrl(env["TODOS_URL"]);
|
|
198
|
-
const configApiUrl = normalizeApiUrl(config.apiUrl);
|
|
199
|
-
const apiUrl = envApiUrl ?? configApiUrl;
|
|
200
|
-
const apiKey = env["TODOS_API_KEY"] || config.apiKey || null;
|
|
201
|
-
return {
|
|
202
|
-
apiUrl,
|
|
203
|
-
apiKey,
|
|
204
|
-
source: {
|
|
205
|
-
apiUrl: envApiUrl ? "TODOS_URL" : configApiUrl ? "config" : "none",
|
|
206
|
-
apiKey: env["TODOS_API_KEY"] ? "TODOS_API_KEY" : config.apiKey ? "config" : "none"
|
|
207
|
-
}
|
|
208
|
-
};
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
// src/sdk/client.ts
|
|
212
|
-
function buildQuery(params) {
|
|
213
|
-
const search = new URLSearchParams;
|
|
214
|
-
for (const [k, v] of Object.entries(params)) {
|
|
215
|
-
if (v !== undefined)
|
|
216
|
-
search.set(k, Array.isArray(v) ? v.join(",") : String(v));
|
|
133
|
+
// src/sdk/v1.generated.ts
|
|
134
|
+
class ApiError extends Error {
|
|
135
|
+
status;
|
|
136
|
+
body;
|
|
137
|
+
constructor(status, message, body) {
|
|
138
|
+
super(message);
|
|
139
|
+
this.status = status;
|
|
140
|
+
this.body = body;
|
|
141
|
+
this.name = "ApiError";
|
|
217
142
|
}
|
|
218
|
-
const s = search.toString();
|
|
219
|
-
return s ? `?${s}` : "";
|
|
220
143
|
}
|
|
221
144
|
|
|
222
|
-
class
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
145
|
+
class TodosV1Client {
|
|
146
|
+
baseUrl;
|
|
147
|
+
apiKey;
|
|
148
|
+
fetchImpl;
|
|
149
|
+
baseHeaders;
|
|
150
|
+
constructor(options) {
|
|
151
|
+
if (!options.baseUrl)
|
|
152
|
+
throw new Error("TodosV1Client requires a baseUrl.");
|
|
153
|
+
this.baseUrl = options.baseUrl.replace(/\/$/, "");
|
|
154
|
+
this.apiKey = options.apiKey;
|
|
155
|
+
this.fetchImpl = options.fetch ?? globalThis.fetch;
|
|
156
|
+
this.baseHeaders = options.headers ?? {};
|
|
226
157
|
}
|
|
227
|
-
async
|
|
228
|
-
|
|
158
|
+
async request(method, path, opts) {
|
|
159
|
+
const url = new URL(this.baseUrl + path);
|
|
160
|
+
if (opts.query) {
|
|
161
|
+
for (const [key, value] of Object.entries(opts.query)) {
|
|
162
|
+
if (value === undefined || value === null)
|
|
163
|
+
continue;
|
|
164
|
+
if (Array.isArray(value)) {
|
|
165
|
+
for (const item of value) {
|
|
166
|
+
if (item !== undefined && item !== null)
|
|
167
|
+
url.searchParams.append(key, String(item));
|
|
168
|
+
}
|
|
169
|
+
} else {
|
|
170
|
+
url.searchParams.set(key, String(value));
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
const headers = { Accept: "application/json", ...this.baseHeaders, ...opts.init?.headers };
|
|
175
|
+
if (this.apiKey)
|
|
176
|
+
headers["x-api-key"] = this.apiKey;
|
|
177
|
+
let payload;
|
|
178
|
+
if (opts.body !== undefined) {
|
|
179
|
+
headers["Content-Type"] = "application/json";
|
|
180
|
+
payload = JSON.stringify(opts.body);
|
|
181
|
+
}
|
|
182
|
+
const response = await this.fetchImpl(url.toString(), { ...opts.init, method, headers, body: payload });
|
|
183
|
+
const text = await response.text();
|
|
184
|
+
const data = text ? (() => {
|
|
185
|
+
try {
|
|
186
|
+
return JSON.parse(text);
|
|
187
|
+
} catch {
|
|
188
|
+
return text;
|
|
189
|
+
}
|
|
190
|
+
})() : undefined;
|
|
191
|
+
if (!response.ok) {
|
|
192
|
+
throw new ApiError(response.status, `${method} ${path} failed: ${response.status}`, data);
|
|
193
|
+
}
|
|
194
|
+
return data;
|
|
229
195
|
}
|
|
230
|
-
async
|
|
231
|
-
|
|
196
|
+
async importSnapshot(body, init) {
|
|
197
|
+
if (body.machines !== undefined && !Array.isArray(body.machines))
|
|
198
|
+
throw new Error("Invalid machine snapshot array; no snapshot was posted");
|
|
199
|
+
if (body.machines?.length) {
|
|
200
|
+
let capability;
|
|
201
|
+
try {
|
|
202
|
+
capability = await this.listMachines(init);
|
|
203
|
+
} catch {
|
|
204
|
+
throw new Error("REMOTE_API_INCOMPATIBLE: machine import requires an upgraded Todos server; no snapshot was posted");
|
|
205
|
+
}
|
|
206
|
+
if (capability?.schema_version !== 2 || !Array.isArray(capability.machines) || !capability.authority || typeof capability.authority.tenant_id !== "string" || !capability.authority.tenant_id || typeof capability.authority.kid !== "string" || !capability.authority.kid)
|
|
207
|
+
throw new Error("REMOTE_API_INCOMPATIBLE: machine registry capability is missing; no snapshot was posted");
|
|
208
|
+
if (body.expected_machine_authority && (body.expected_machine_authority.kid !== capability.authority.kid || body.expected_machine_authority.tenant_id !== capability.authority.tenant_id))
|
|
209
|
+
throw new Error("Machine migration authority changed before POST; no snapshot was posted");
|
|
210
|
+
body = { ...body, expected_machine_authority: { ...capability.authority } };
|
|
211
|
+
}
|
|
212
|
+
const result = await this.request("POST", `/v1/import`, {
|
|
213
|
+
body,
|
|
214
|
+
query: undefined,
|
|
215
|
+
init
|
|
216
|
+
});
|
|
217
|
+
if (body.machines?.length && (result.machine_authority?.kid !== body.expected_machine_authority?.kid || result.machine_authority?.tenant_id !== body.expected_machine_authority?.tenant_id))
|
|
218
|
+
throw new Error("Machine receipt authority changed; preserve the source and inspect before retrying");
|
|
219
|
+
return result;
|
|
232
220
|
}
|
|
233
|
-
async
|
|
234
|
-
return this.
|
|
221
|
+
async listMachines(init) {
|
|
222
|
+
return this.request("GET", `/v1/machines`, {
|
|
223
|
+
body: undefined,
|
|
224
|
+
query: undefined,
|
|
225
|
+
init
|
|
226
|
+
});
|
|
235
227
|
}
|
|
236
|
-
async
|
|
237
|
-
return this.
|
|
228
|
+
async mutateMachineRegistry(body, init) {
|
|
229
|
+
return this.request("POST", `/v1/machines`, {
|
|
230
|
+
body,
|
|
231
|
+
query: undefined,
|
|
232
|
+
init
|
|
233
|
+
});
|
|
238
234
|
}
|
|
239
|
-
async
|
|
240
|
-
return this.
|
|
235
|
+
async listPlans(query, init) {
|
|
236
|
+
return this.request("GET", `/v1/plans`, {
|
|
237
|
+
body: undefined,
|
|
238
|
+
query,
|
|
239
|
+
init
|
|
240
|
+
});
|
|
241
241
|
}
|
|
242
|
-
async
|
|
243
|
-
return this.
|
|
242
|
+
async createPlan(body, init) {
|
|
243
|
+
return this.request("POST", `/v1/plans`, {
|
|
244
|
+
body,
|
|
245
|
+
query: undefined,
|
|
246
|
+
init
|
|
247
|
+
});
|
|
244
248
|
}
|
|
245
|
-
async
|
|
246
|
-
return this.
|
|
249
|
+
async getPlan(id, init) {
|
|
250
|
+
return this.request("GET", `/v1/plans/${encodeURIComponent(String(id))}`, {
|
|
251
|
+
body: undefined,
|
|
252
|
+
query: undefined,
|
|
253
|
+
init
|
|
254
|
+
});
|
|
247
255
|
}
|
|
248
|
-
async
|
|
249
|
-
return this.
|
|
256
|
+
async deletePlan(id, init) {
|
|
257
|
+
return this.request("DELETE", `/v1/plans/${encodeURIComponent(String(id))}`, {
|
|
258
|
+
body: undefined,
|
|
259
|
+
query: undefined,
|
|
260
|
+
init
|
|
261
|
+
});
|
|
250
262
|
}
|
|
251
|
-
async
|
|
252
|
-
return this.
|
|
263
|
+
async updatePlan(id, body, init) {
|
|
264
|
+
return this.request("PATCH", `/v1/plans/${encodeURIComponent(String(id))}`, {
|
|
265
|
+
body,
|
|
266
|
+
query: undefined,
|
|
267
|
+
init
|
|
268
|
+
});
|
|
253
269
|
}
|
|
254
|
-
async
|
|
255
|
-
return this.
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
270
|
+
async listPlanComments(id, query, init) {
|
|
271
|
+
return this.request("GET", `/v1/plans/${encodeURIComponent(String(id))}/comments`, {
|
|
272
|
+
body: undefined,
|
|
273
|
+
query,
|
|
274
|
+
init
|
|
259
275
|
});
|
|
260
276
|
}
|
|
261
|
-
async
|
|
262
|
-
return this.
|
|
277
|
+
async deletePlanPreserving(id, body, init) {
|
|
278
|
+
return this.request("POST", `/v1/plans/${encodeURIComponent(String(id))}/delete-preserving`, {
|
|
279
|
+
body,
|
|
280
|
+
query: undefined,
|
|
281
|
+
init
|
|
282
|
+
});
|
|
263
283
|
}
|
|
264
|
-
async
|
|
265
|
-
return this.
|
|
284
|
+
async planPlanProjectLink(id, query, init) {
|
|
285
|
+
return this.request("GET", `/v1/plans/${encodeURIComponent(String(id))}/project-link`, {
|
|
286
|
+
body: undefined,
|
|
287
|
+
query,
|
|
288
|
+
init
|
|
289
|
+
});
|
|
266
290
|
}
|
|
267
|
-
async
|
|
268
|
-
return this.
|
|
291
|
+
async applyPlanProjectLink(id, body, init) {
|
|
292
|
+
return this.request("POST", `/v1/plans/${encodeURIComponent(String(id))}/project-link`, {
|
|
293
|
+
body,
|
|
294
|
+
query: undefined,
|
|
295
|
+
init
|
|
296
|
+
});
|
|
269
297
|
}
|
|
270
|
-
async
|
|
271
|
-
return this.
|
|
298
|
+
async rollbackPlanProjectLink(id, body, init) {
|
|
299
|
+
return this.request("POST", `/v1/plans/${encodeURIComponent(String(id))}/project-link/rollback`, {
|
|
300
|
+
body,
|
|
301
|
+
query: undefined,
|
|
302
|
+
init
|
|
303
|
+
});
|
|
272
304
|
}
|
|
273
|
-
async
|
|
274
|
-
return this.
|
|
305
|
+
async admitPrGroup(body, init) {
|
|
306
|
+
return this.request("POST", `/v1/pr-groups/admit`, {
|
|
307
|
+
body,
|
|
308
|
+
query: undefined,
|
|
309
|
+
init
|
|
310
|
+
});
|
|
275
311
|
}
|
|
276
|
-
async
|
|
277
|
-
return this.
|
|
312
|
+
async getPrGroupState(id, init) {
|
|
313
|
+
return this.request("GET", `/v1/pr-groups/${encodeURIComponent(String(id))}`, {
|
|
314
|
+
body: undefined,
|
|
315
|
+
query: undefined,
|
|
316
|
+
init
|
|
317
|
+
});
|
|
278
318
|
}
|
|
279
|
-
async
|
|
280
|
-
return this.
|
|
319
|
+
async getPrGroupEvents(id, query, init) {
|
|
320
|
+
return this.request("GET", `/v1/pr-groups/${encodeURIComponent(String(id))}/events`, {
|
|
321
|
+
body: undefined,
|
|
322
|
+
query,
|
|
323
|
+
init
|
|
324
|
+
});
|
|
281
325
|
}
|
|
282
|
-
async
|
|
283
|
-
return this.
|
|
326
|
+
async appendPrGroupEvent(id, body, init) {
|
|
327
|
+
return this.request("POST", `/v1/pr-groups/${encodeURIComponent(String(id))}/events`, {
|
|
328
|
+
body,
|
|
329
|
+
query: undefined,
|
|
330
|
+
init
|
|
331
|
+
});
|
|
284
332
|
}
|
|
285
|
-
async
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
fields: options?.fields
|
|
333
|
+
async recoverPrGroup(id, body, init) {
|
|
334
|
+
return this.request("POST", `/v1/pr-groups/${encodeURIComponent(String(id))}/recover`, {
|
|
335
|
+
body,
|
|
336
|
+
query: undefined,
|
|
337
|
+
init
|
|
291
338
|
});
|
|
292
|
-
const url = `${this.client.baseUrl}/api/tasks/context${q}`;
|
|
293
|
-
const res = await this.client._fetchRaw(url);
|
|
294
|
-
if (!res.ok)
|
|
295
|
-
return options?.format === "json" ? {} : "";
|
|
296
|
-
if (options?.format === "json")
|
|
297
|
-
return res.json();
|
|
298
|
-
return res.text();
|
|
299
339
|
}
|
|
300
|
-
async
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
if (options?.format === "csv")
|
|
307
|
-
return res.text();
|
|
308
|
-
return res.json();
|
|
340
|
+
async getAtomicProjectMigrationCapability(init) {
|
|
341
|
+
return this.request("GET", `/v1/project-migrations`, {
|
|
342
|
+
body: undefined,
|
|
343
|
+
query: undefined,
|
|
344
|
+
init
|
|
345
|
+
});
|
|
309
346
|
}
|
|
310
|
-
async
|
|
311
|
-
return this.
|
|
347
|
+
async importAtomicProjectSnapshot(body, init) {
|
|
348
|
+
return this.request("POST", `/v1/project-migrations`, {
|
|
349
|
+
body,
|
|
350
|
+
query: undefined,
|
|
351
|
+
init
|
|
352
|
+
});
|
|
312
353
|
}
|
|
313
|
-
async
|
|
314
|
-
return this.
|
|
354
|
+
async getProjectRegistrationCapability(init) {
|
|
355
|
+
return this.request("GET", `/v1/project-registration/capability`, {
|
|
356
|
+
body: undefined,
|
|
357
|
+
query: undefined,
|
|
358
|
+
init
|
|
359
|
+
});
|
|
315
360
|
}
|
|
316
|
-
async
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
361
|
+
async compensateProjectRegistrationResource(body, init) {
|
|
362
|
+
return this.request("POST", `/v1/project-registration/compensate`, {
|
|
363
|
+
body,
|
|
364
|
+
query: undefined,
|
|
365
|
+
init
|
|
321
366
|
});
|
|
322
|
-
const url = `${this.client.baseUrl}/api/tasks/stream${q}`;
|
|
323
|
-
const resp = await this.client._fetchRaw(url);
|
|
324
|
-
if (!resp.ok || !resp.body)
|
|
325
|
-
throw new Error(`SSE connection failed: ${resp.status}`);
|
|
326
|
-
const reader = resp.body.getReader();
|
|
327
|
-
const decoder = new TextDecoder;
|
|
328
|
-
let buffer = "";
|
|
329
|
-
try {
|
|
330
|
-
while (true) {
|
|
331
|
-
const { done, value } = await reader.read();
|
|
332
|
-
if (done)
|
|
333
|
-
break;
|
|
334
|
-
buffer += decoder.decode(value, { stream: true });
|
|
335
|
-
const lines = buffer.split(`
|
|
336
|
-
`);
|
|
337
|
-
buffer = lines.pop() || "";
|
|
338
|
-
for (const line of lines) {
|
|
339
|
-
if (line.startsWith("data: ")) {
|
|
340
|
-
try {
|
|
341
|
-
const data = JSON.parse(line.slice(6));
|
|
342
|
-
if (data.type !== "connected")
|
|
343
|
-
yield data;
|
|
344
|
-
} catch {}
|
|
345
|
-
}
|
|
346
|
-
}
|
|
347
|
-
}
|
|
348
|
-
} finally {
|
|
349
|
-
reader.releaseLock();
|
|
350
|
-
}
|
|
351
367
|
}
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
368
|
+
async createProjectRegistrationResource(body, init) {
|
|
369
|
+
return this.request("POST", `/v1/project-registration/create`, {
|
|
370
|
+
body,
|
|
371
|
+
query: undefined,
|
|
372
|
+
init
|
|
373
|
+
});
|
|
358
374
|
}
|
|
359
|
-
async
|
|
360
|
-
return this.
|
|
375
|
+
async readExactProjectRegistrationResource(body, init) {
|
|
376
|
+
return this.request("POST", `/v1/project-registration/read-exact`, {
|
|
377
|
+
body,
|
|
378
|
+
query: undefined,
|
|
379
|
+
init
|
|
380
|
+
});
|
|
361
381
|
}
|
|
362
|
-
async
|
|
363
|
-
return this.
|
|
382
|
+
async lookupProjectRegistrationReceipt(body, init) {
|
|
383
|
+
return this.request("POST", `/v1/project-registration/receipts/lookup`, {
|
|
384
|
+
body,
|
|
385
|
+
query: undefined,
|
|
386
|
+
init
|
|
387
|
+
});
|
|
364
388
|
}
|
|
365
|
-
async
|
|
366
|
-
return this.
|
|
389
|
+
async listProjectRegistrationResources(query, init) {
|
|
390
|
+
return this.request("GET", `/v1/project-registration/resources`, {
|
|
391
|
+
body: undefined,
|
|
392
|
+
query,
|
|
393
|
+
init
|
|
394
|
+
});
|
|
367
395
|
}
|
|
368
|
-
async
|
|
369
|
-
|
|
396
|
+
async validatePriorRegistrationAdoption(body, init) {
|
|
397
|
+
const response = await this.request("POST", `/v1/project-registration/validate-prior-adoption`, {
|
|
398
|
+
body,
|
|
399
|
+
query: undefined,
|
|
400
|
+
init
|
|
401
|
+
});
|
|
402
|
+
return {
|
|
403
|
+
validation: assertTodosPriorRegistrationAdoptionValidationEnvelope(response, body)
|
|
404
|
+
};
|
|
370
405
|
}
|
|
371
|
-
async
|
|
372
|
-
return this.
|
|
406
|
+
async verifyInverseProjectRegistrationResource(body, init) {
|
|
407
|
+
return this.request("POST", `/v1/project-registration/verify-inverse`, {
|
|
408
|
+
body,
|
|
409
|
+
query: undefined,
|
|
410
|
+
init
|
|
411
|
+
});
|
|
373
412
|
}
|
|
374
|
-
async
|
|
375
|
-
return this.
|
|
413
|
+
async listProjects(init) {
|
|
414
|
+
return this.request("GET", `/v1/projects`, {
|
|
415
|
+
body: undefined,
|
|
416
|
+
query: undefined,
|
|
417
|
+
init
|
|
418
|
+
});
|
|
376
419
|
}
|
|
377
|
-
async
|
|
378
|
-
return this.
|
|
420
|
+
async createProject(body, init) {
|
|
421
|
+
return this.request("POST", `/v1/projects`, {
|
|
422
|
+
body,
|
|
423
|
+
query: undefined,
|
|
424
|
+
init
|
|
425
|
+
});
|
|
379
426
|
}
|
|
380
|
-
async
|
|
381
|
-
return this.
|
|
427
|
+
async getProject(id, init) {
|
|
428
|
+
return this.request("GET", `/v1/projects/${encodeURIComponent(String(id))}`, {
|
|
429
|
+
body: undefined,
|
|
430
|
+
query: undefined,
|
|
431
|
+
init
|
|
432
|
+
});
|
|
382
433
|
}
|
|
383
|
-
async
|
|
384
|
-
return this.
|
|
434
|
+
async deleteProject(id, init) {
|
|
435
|
+
return this.request("DELETE", `/v1/projects/${encodeURIComponent(String(id))}`, {
|
|
436
|
+
body: undefined,
|
|
437
|
+
query: undefined,
|
|
438
|
+
init
|
|
439
|
+
});
|
|
385
440
|
}
|
|
386
|
-
async
|
|
387
|
-
return this.
|
|
441
|
+
async updateProject(id, body, init) {
|
|
442
|
+
return this.request("PATCH", `/v1/projects/${encodeURIComponent(String(id))}`, {
|
|
443
|
+
body,
|
|
444
|
+
query: undefined,
|
|
445
|
+
init
|
|
446
|
+
});
|
|
388
447
|
}
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
448
|
+
async deleteProjectPreserving(id, body, init) {
|
|
449
|
+
return this.request("POST", `/v1/projects/${encodeURIComponent(String(id))}/delete-preserving`, {
|
|
450
|
+
body,
|
|
451
|
+
query: undefined,
|
|
452
|
+
init
|
|
453
|
+
});
|
|
395
454
|
}
|
|
396
|
-
async
|
|
397
|
-
return this.
|
|
455
|
+
async renameProject(id, body, init) {
|
|
456
|
+
return this.request("POST", `/v1/projects/${encodeURIComponent(String(id))}/rename`, {
|
|
457
|
+
body,
|
|
458
|
+
query: undefined,
|
|
459
|
+
init
|
|
460
|
+
});
|
|
398
461
|
}
|
|
399
|
-
async
|
|
400
|
-
return this.
|
|
462
|
+
async planProjectTaskListEnsure(id, init) {
|
|
463
|
+
return this.request("GET", `/v1/projects/${encodeURIComponent(String(id))}/task-list/ensure`, {
|
|
464
|
+
body: undefined,
|
|
465
|
+
query: undefined,
|
|
466
|
+
init
|
|
467
|
+
});
|
|
401
468
|
}
|
|
402
|
-
async
|
|
403
|
-
return this.
|
|
469
|
+
async ensureProjectTaskList(id, body, init) {
|
|
470
|
+
return this.request("POST", `/v1/projects/${encodeURIComponent(String(id))}/task-list/ensure`, {
|
|
471
|
+
body,
|
|
472
|
+
query: undefined,
|
|
473
|
+
init
|
|
474
|
+
});
|
|
404
475
|
}
|
|
405
|
-
async
|
|
406
|
-
return this.
|
|
476
|
+
async rollbackProjectTaskListEnsure(id, body, init) {
|
|
477
|
+
return this.request("POST", `/v1/projects/${encodeURIComponent(String(id))}/task-list/rollback`, {
|
|
478
|
+
body,
|
|
479
|
+
query: undefined,
|
|
480
|
+
init
|
|
481
|
+
});
|
|
407
482
|
}
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
}
|
|
415
|
-
async list(projectId) {
|
|
416
|
-
return this.client._get("/api/plans", projectId ? `?project_id=${projectId}` : "");
|
|
483
|
+
async findTaskGitRefs(ref, init) {
|
|
484
|
+
return this.request("GET", `/v1/refs/${encodeURIComponent(String(ref))}`, {
|
|
485
|
+
body: undefined,
|
|
486
|
+
query: undefined,
|
|
487
|
+
init
|
|
488
|
+
});
|
|
417
489
|
}
|
|
418
|
-
async
|
|
419
|
-
return this.
|
|
490
|
+
async getStats(init) {
|
|
491
|
+
return this.request("GET", `/v1/stats`, {
|
|
492
|
+
body: undefined,
|
|
493
|
+
query: undefined,
|
|
494
|
+
init
|
|
495
|
+
});
|
|
420
496
|
}
|
|
421
|
-
async
|
|
422
|
-
return this.
|
|
497
|
+
async listTaskLists(query, init) {
|
|
498
|
+
return this.request("GET", `/v1/task-lists`, {
|
|
499
|
+
body: undefined,
|
|
500
|
+
query,
|
|
501
|
+
init
|
|
502
|
+
});
|
|
423
503
|
}
|
|
424
|
-
async
|
|
425
|
-
return this.
|
|
504
|
+
async createTaskList(body, init) {
|
|
505
|
+
return this.request("POST", `/v1/task-lists`, {
|
|
506
|
+
body,
|
|
507
|
+
query: undefined,
|
|
508
|
+
init
|
|
509
|
+
});
|
|
426
510
|
}
|
|
427
|
-
async
|
|
428
|
-
return this.
|
|
511
|
+
async getTaskList(id, init) {
|
|
512
|
+
return this.request("GET", `/v1/task-lists/${encodeURIComponent(String(id))}`, {
|
|
513
|
+
body: undefined,
|
|
514
|
+
query: undefined,
|
|
515
|
+
init
|
|
516
|
+
});
|
|
429
517
|
}
|
|
430
|
-
async
|
|
431
|
-
return this.
|
|
518
|
+
async deleteTaskList(id, init) {
|
|
519
|
+
return this.request("DELETE", `/v1/task-lists/${encodeURIComponent(String(id))}`, {
|
|
520
|
+
body: undefined,
|
|
521
|
+
query: undefined,
|
|
522
|
+
init
|
|
523
|
+
});
|
|
432
524
|
}
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
525
|
+
async updateTaskList(id, body, init) {
|
|
526
|
+
return this.request("PATCH", `/v1/task-lists/${encodeURIComponent(String(id))}`, {
|
|
527
|
+
body,
|
|
528
|
+
query: undefined,
|
|
529
|
+
init
|
|
530
|
+
});
|
|
439
531
|
}
|
|
440
|
-
async
|
|
441
|
-
return this.
|
|
532
|
+
async deleteTaskListPreserving(id, body, init) {
|
|
533
|
+
return this.request("POST", `/v1/task-lists/${encodeURIComponent(String(id))}/delete-preserving`, {
|
|
534
|
+
body,
|
|
535
|
+
query: undefined,
|
|
536
|
+
init
|
|
537
|
+
});
|
|
442
538
|
}
|
|
443
|
-
async
|
|
444
|
-
return this.
|
|
539
|
+
async applyTaskManifest(body, init) {
|
|
540
|
+
return this.request("POST", `/v1/task-manifest/apply`, {
|
|
541
|
+
body,
|
|
542
|
+
query: undefined,
|
|
543
|
+
init
|
|
544
|
+
});
|
|
445
545
|
}
|
|
446
|
-
async
|
|
447
|
-
return this.
|
|
546
|
+
async lookupTaskManifestBinding(body, init) {
|
|
547
|
+
return this.request("POST", `/v1/task-manifest/bindings/lookup`, {
|
|
548
|
+
body,
|
|
549
|
+
query: undefined,
|
|
550
|
+
init
|
|
551
|
+
});
|
|
448
552
|
}
|
|
449
|
-
async
|
|
450
|
-
return this.
|
|
553
|
+
async getTaskManifestCapability(init) {
|
|
554
|
+
return this.request("GET", `/v1/task-manifest/capability`, {
|
|
555
|
+
body: undefined,
|
|
556
|
+
query: undefined,
|
|
557
|
+
init
|
|
558
|
+
});
|
|
451
559
|
}
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
560
|
+
async compensateTaskManifest(body, init) {
|
|
561
|
+
return this.request("POST", `/v1/task-manifest/compensate`, {
|
|
562
|
+
body,
|
|
563
|
+
query: undefined,
|
|
564
|
+
init
|
|
565
|
+
});
|
|
458
566
|
}
|
|
459
|
-
async
|
|
460
|
-
return this.
|
|
567
|
+
async readExactTaskManifest(body, init) {
|
|
568
|
+
return this.request("POST", `/v1/task-manifest/read-exact`, {
|
|
569
|
+
body,
|
|
570
|
+
query: undefined,
|
|
571
|
+
init
|
|
572
|
+
});
|
|
461
573
|
}
|
|
462
|
-
async
|
|
463
|
-
return this.
|
|
574
|
+
async applyTaskSubtreeTransfer(body, init) {
|
|
575
|
+
return this.request("POST", `/v1/task-subtree-transfer/apply`, {
|
|
576
|
+
body,
|
|
577
|
+
query: undefined,
|
|
578
|
+
init
|
|
579
|
+
});
|
|
464
580
|
}
|
|
465
|
-
async
|
|
466
|
-
return this.
|
|
581
|
+
async getTaskSubtreeTransferCapability(init) {
|
|
582
|
+
return this.request("GET", `/v1/task-subtree-transfer/capability`, {
|
|
583
|
+
body: undefined,
|
|
584
|
+
query: undefined,
|
|
585
|
+
init
|
|
586
|
+
});
|
|
467
587
|
}
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
588
|
+
async inspectTaskSubtreeTransfer(body, init) {
|
|
589
|
+
return this.request("POST", `/v1/task-subtree-transfer/inspect`, {
|
|
590
|
+
body,
|
|
591
|
+
query: undefined,
|
|
592
|
+
init
|
|
593
|
+
});
|
|
474
594
|
}
|
|
475
|
-
async
|
|
476
|
-
return this.
|
|
595
|
+
async readExactTaskSubtreeTransfer(body, init) {
|
|
596
|
+
return this.request("POST", `/v1/task-subtree-transfer/read-exact`, {
|
|
597
|
+
body,
|
|
598
|
+
query: undefined,
|
|
599
|
+
init
|
|
600
|
+
});
|
|
477
601
|
}
|
|
478
|
-
async
|
|
479
|
-
return this.
|
|
602
|
+
async rollbackTaskSubtreeTransfer(body, init) {
|
|
603
|
+
return this.request("POST", `/v1/task-subtree-transfer/rollback`, {
|
|
604
|
+
body,
|
|
605
|
+
query: undefined,
|
|
606
|
+
init
|
|
607
|
+
});
|
|
480
608
|
}
|
|
481
|
-
async
|
|
482
|
-
return this.
|
|
609
|
+
async listTasks(query, init) {
|
|
610
|
+
return this.request("GET", `/v1/tasks`, {
|
|
611
|
+
body: undefined,
|
|
612
|
+
query,
|
|
613
|
+
init
|
|
614
|
+
});
|
|
483
615
|
}
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
616
|
+
async createTask(body, init) {
|
|
617
|
+
return this.request("POST", `/v1/tasks`, {
|
|
618
|
+
body,
|
|
619
|
+
query: undefined,
|
|
620
|
+
init
|
|
621
|
+
});
|
|
490
622
|
}
|
|
491
|
-
async
|
|
492
|
-
return this.
|
|
623
|
+
async getTask(id, init) {
|
|
624
|
+
return this.request("GET", `/v1/tasks/${encodeURIComponent(String(id))}`, {
|
|
625
|
+
body: undefined,
|
|
626
|
+
query: undefined,
|
|
627
|
+
init
|
|
628
|
+
});
|
|
493
629
|
}
|
|
494
|
-
async
|
|
495
|
-
|
|
496
|
-
|
|
630
|
+
async deleteTask(id, init) {
|
|
631
|
+
return this.request("DELETE", `/v1/tasks/${encodeURIComponent(String(id))}`, {
|
|
632
|
+
body: undefined,
|
|
633
|
+
query: undefined,
|
|
634
|
+
init
|
|
635
|
+
});
|
|
497
636
|
}
|
|
498
|
-
async
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
637
|
+
async updateTask(id, body, init) {
|
|
638
|
+
return this.request("PATCH", `/v1/tasks/${encodeURIComponent(String(id))}`, {
|
|
639
|
+
body,
|
|
640
|
+
query: undefined,
|
|
641
|
+
init
|
|
642
|
+
});
|
|
504
643
|
}
|
|
505
|
-
async
|
|
506
|
-
return this.
|
|
644
|
+
async listTaskComments(id, query, init) {
|
|
645
|
+
return this.request("GET", `/v1/tasks/${encodeURIComponent(String(id))}/comments`, {
|
|
646
|
+
body: undefined,
|
|
647
|
+
query,
|
|
648
|
+
init
|
|
649
|
+
});
|
|
507
650
|
}
|
|
508
|
-
async
|
|
509
|
-
return this.
|
|
651
|
+
async createTaskComment(id, body, init) {
|
|
652
|
+
return this.request("POST", `/v1/tasks/${encodeURIComponent(String(id))}/comments`, {
|
|
653
|
+
body,
|
|
654
|
+
query: undefined,
|
|
655
|
+
init
|
|
656
|
+
});
|
|
510
657
|
}
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
maxRetries;
|
|
518
|
-
retryDelay;
|
|
519
|
-
tasks;
|
|
520
|
-
agents;
|
|
521
|
-
projects;
|
|
522
|
-
plans;
|
|
523
|
-
orgs;
|
|
524
|
-
webhooks;
|
|
525
|
-
templates;
|
|
526
|
-
prGroups;
|
|
527
|
-
constructor(options = {}) {
|
|
528
|
-
const localConfig = getLocalApiConfig();
|
|
529
|
-
this.baseUrl = normalizeApiUrl(options.baseUrl) || localConfig.apiUrl || "http://localhost:19427";
|
|
530
|
-
this.timeout = options.timeout ?? 1e4;
|
|
531
|
-
this.apiKey = options.apiKey || localConfig.apiKey;
|
|
532
|
-
this.maxRetries = options.maxRetries ?? 0;
|
|
533
|
-
this.retryDelay = options.retryDelay ?? 1000;
|
|
534
|
-
this.tasks = new TasksResource(this);
|
|
535
|
-
this.agents = new AgentsResource(this);
|
|
536
|
-
this.projects = new ProjectsResource(this);
|
|
537
|
-
this.plans = new PlansResource(this);
|
|
538
|
-
this.orgs = new OrgsResource(this);
|
|
539
|
-
this.webhooks = new WebhooksResource(this);
|
|
540
|
-
this.templates = new TemplatesResource(this);
|
|
541
|
-
this.prGroups = new PrGroupsResource(this);
|
|
658
|
+
async completeTask(id, body, init) {
|
|
659
|
+
return this.request("POST", `/v1/tasks/${encodeURIComponent(String(id))}/complete`, {
|
|
660
|
+
body,
|
|
661
|
+
query: undefined,
|
|
662
|
+
init
|
|
663
|
+
});
|
|
542
664
|
}
|
|
543
|
-
|
|
544
|
-
return
|
|
665
|
+
async failTask(id, body, init) {
|
|
666
|
+
return this.request("POST", `/v1/tasks/${encodeURIComponent(String(id))}/fail`, {
|
|
667
|
+
body,
|
|
668
|
+
query: undefined,
|
|
669
|
+
init
|
|
670
|
+
});
|
|
545
671
|
}
|
|
546
|
-
async
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
} finally {
|
|
553
|
-
clearTimeout(timer);
|
|
554
|
-
}
|
|
672
|
+
async listTaskGitRefs(id, init) {
|
|
673
|
+
return this.request("GET", `/v1/tasks/${encodeURIComponent(String(id))}/refs`, {
|
|
674
|
+
body: undefined,
|
|
675
|
+
query: undefined,
|
|
676
|
+
init
|
|
677
|
+
});
|
|
555
678
|
}
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
existing.forEach((v, k) => {
|
|
563
|
-
headers[k] = v;
|
|
564
|
-
});
|
|
565
|
-
} else if (Array.isArray(existing)) {
|
|
566
|
-
for (const [k, v] of existing)
|
|
567
|
-
headers[k] = v;
|
|
568
|
-
} else {
|
|
569
|
-
Object.assign(headers, existing);
|
|
570
|
-
}
|
|
571
|
-
}
|
|
572
|
-
return headers;
|
|
679
|
+
async linkTaskGitRef(id, body, init) {
|
|
680
|
+
return this.request("POST", `/v1/tasks/${encodeURIComponent(String(id))}/refs`, {
|
|
681
|
+
body,
|
|
682
|
+
query: undefined,
|
|
683
|
+
init
|
|
684
|
+
});
|
|
573
685
|
}
|
|
574
|
-
async
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
} catch (e) {
|
|
581
|
-
lastError = e;
|
|
582
|
-
if (e instanceof TodosAPIError && e.status < 500 && e.status !== 429)
|
|
583
|
-
throw e;
|
|
584
|
-
if (e instanceof TodosUnauthorizedError || e instanceof TodosNotFoundError || e instanceof TodosConflictError)
|
|
585
|
-
throw e;
|
|
586
|
-
if (attempt < maxAttempts - 1) {
|
|
587
|
-
const delay = this.retryDelay * Math.pow(2, attempt);
|
|
588
|
-
if (e instanceof TodosRateLimitError) {
|
|
589
|
-
await this._sleep(e.retryAfter * 1000);
|
|
590
|
-
} else {
|
|
591
|
-
await this._sleep(delay);
|
|
592
|
-
}
|
|
593
|
-
}
|
|
594
|
-
}
|
|
595
|
-
}
|
|
596
|
-
throw lastError || new Error("Request failed after retries");
|
|
686
|
+
async handoffStaleTaskLock(id, body, init) {
|
|
687
|
+
return this.request("POST", `/v1/tasks/${encodeURIComponent(String(id))}/stale-lock-handoff`, {
|
|
688
|
+
body,
|
|
689
|
+
query: undefined,
|
|
690
|
+
init
|
|
691
|
+
});
|
|
597
692
|
}
|
|
598
|
-
async
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
const res = await fetch(url, { ...init, headers, signal: controller.signal });
|
|
605
|
-
if (!res.ok) {
|
|
606
|
-
const body = await res.json().catch(() => ({ error: res.statusText }));
|
|
607
|
-
const message = body.error || `HTTP ${res.status}: ${res.statusText}`;
|
|
608
|
-
if (res.status === 401)
|
|
609
|
-
throw new TodosUnauthorizedError(message, body);
|
|
610
|
-
if (res.status === 404)
|
|
611
|
-
throw new TodosNotFoundError(message, body);
|
|
612
|
-
if (res.status === 409)
|
|
613
|
-
throw new TodosConflictError(message, body);
|
|
614
|
-
if (res.status === 429) {
|
|
615
|
-
const retryAfter = parseInt(res.headers.get("retry-after") || "60", 10);
|
|
616
|
-
throw new TodosRateLimitError(message, retryAfter, body);
|
|
617
|
-
}
|
|
618
|
-
throw new TodosAPIError(message, res.status, res.statusText, body);
|
|
619
|
-
}
|
|
620
|
-
if (res.status === 204)
|
|
621
|
-
return null;
|
|
622
|
-
const text = await res.text();
|
|
623
|
-
if (text.length === 0)
|
|
624
|
-
return null;
|
|
625
|
-
return JSON.parse(text);
|
|
626
|
-
} catch (e) {
|
|
627
|
-
if (e instanceof DOMException && e.name === "AbortError") {
|
|
628
|
-
throw new TodosTimeoutError(this.timeout);
|
|
629
|
-
}
|
|
630
|
-
throw e;
|
|
631
|
-
} finally {
|
|
632
|
-
clearTimeout(timer);
|
|
633
|
-
}
|
|
693
|
+
async startTask(id, init) {
|
|
694
|
+
return this.request("POST", `/v1/tasks/${encodeURIComponent(String(id))}/start`, {
|
|
695
|
+
body: undefined,
|
|
696
|
+
query: undefined,
|
|
697
|
+
init
|
|
698
|
+
});
|
|
634
699
|
}
|
|
635
|
-
async
|
|
636
|
-
return this.
|
|
700
|
+
async listTemplates(query, init) {
|
|
701
|
+
return this.request("GET", `/v1/templates`, {
|
|
702
|
+
body: undefined,
|
|
703
|
+
query,
|
|
704
|
+
init
|
|
705
|
+
});
|
|
637
706
|
}
|
|
638
|
-
async
|
|
639
|
-
return this.
|
|
640
|
-
|
|
641
|
-
|
|
707
|
+
async createTemplate(body, init) {
|
|
708
|
+
return this.request("POST", `/v1/templates`, {
|
|
709
|
+
body,
|
|
710
|
+
query: undefined,
|
|
711
|
+
init
|
|
642
712
|
});
|
|
643
713
|
}
|
|
644
|
-
async
|
|
645
|
-
return this.
|
|
646
|
-
|
|
647
|
-
|
|
714
|
+
async initializeTemplates(body, init) {
|
|
715
|
+
return this.request("POST", `/v1/templates/initialize`, {
|
|
716
|
+
body,
|
|
717
|
+
query: undefined,
|
|
718
|
+
init
|
|
648
719
|
});
|
|
649
720
|
}
|
|
650
|
-
async
|
|
651
|
-
return this.
|
|
721
|
+
async getTemplate(id, init) {
|
|
722
|
+
return this.request("GET", `/v1/templates/${encodeURIComponent(String(id))}`, {
|
|
723
|
+
body: undefined,
|
|
724
|
+
query: undefined,
|
|
725
|
+
init
|
|
726
|
+
});
|
|
652
727
|
}
|
|
653
|
-
|
|
654
|
-
return
|
|
728
|
+
async deleteTemplate(id, init) {
|
|
729
|
+
return this.request("DELETE", `/v1/templates/${encodeURIComponent(String(id))}`, {
|
|
730
|
+
body: undefined,
|
|
731
|
+
query: undefined,
|
|
732
|
+
init
|
|
733
|
+
});
|
|
655
734
|
}
|
|
656
|
-
async
|
|
657
|
-
return this.
|
|
735
|
+
async updateTemplate(id, body, init) {
|
|
736
|
+
return this.request("PATCH", `/v1/templates/${encodeURIComponent(String(id))}`, {
|
|
737
|
+
body,
|
|
738
|
+
query: undefined,
|
|
739
|
+
init
|
|
740
|
+
});
|
|
658
741
|
}
|
|
659
|
-
async
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
}
|
|
742
|
+
async getTemplateHistory(id, init) {
|
|
743
|
+
return this.request("GET", `/v1/templates/${encodeURIComponent(String(id))}/history`, {
|
|
744
|
+
body: undefined,
|
|
745
|
+
query: undefined,
|
|
746
|
+
init
|
|
747
|
+
});
|
|
666
748
|
}
|
|
667
|
-
|
|
668
|
-
|
|
749
|
+
}
|
|
750
|
+
|
|
751
|
+
// src/lib/local-opt-in.ts
|
|
752
|
+
import {
|
|
753
|
+
clientTransportEnvKeys,
|
|
754
|
+
credentialOverrideEnvKey,
|
|
755
|
+
credentialPointerEnvKey,
|
|
756
|
+
CREDENTIAL_PROFILE_ENV_KEY
|
|
757
|
+
} from "@hasna/contracts/client";
|
|
758
|
+
var TODOS_LOCAL_OPT_IN_ENV_KEYS = ["HASNA_TODOS_LOCAL", "TODOS_LOCAL"];
|
|
759
|
+
function isTodosLocalOptIn(env = process.env) {
|
|
760
|
+
return TODOS_LOCAL_OPT_IN_ENV_KEYS.some((key) => (env[key] ?? "").trim() !== "");
|
|
761
|
+
}
|
|
762
|
+
function todosAuthorityEnvKeys() {
|
|
763
|
+
const keys = clientTransportEnvKeys("todos");
|
|
764
|
+
return [
|
|
765
|
+
...keys.apiUrlKeys,
|
|
766
|
+
...keys.apiKeyKeys,
|
|
767
|
+
credentialOverrideEnvKey("todos"),
|
|
768
|
+
credentialPointerEnvKey("todos"),
|
|
769
|
+
CREDENTIAL_PROFILE_ENV_KEY
|
|
770
|
+
];
|
|
771
|
+
}
|
|
772
|
+
function hasTodosEnvAuthorityIntent(env = process.env) {
|
|
773
|
+
return todosAuthorityEnvKeys().some((key) => (env[key] ?? "").trim() !== "");
|
|
774
|
+
}
|
|
775
|
+
function selectsTodosLocalStore(env = process.env) {
|
|
776
|
+
return !hasTodosEnvAuthorityIntent(env) && isTodosLocalOptIn(env);
|
|
777
|
+
}
|
|
778
|
+
function todosResolverEnv(env) {
|
|
779
|
+
const blanks = todosAuthorityEnvKeys().filter((key) => (key in env) && (env[key] ?? "").trim() === "");
|
|
780
|
+
if (blanks.length === 0)
|
|
781
|
+
return env;
|
|
782
|
+
const next = { ...env };
|
|
783
|
+
for (const key of blanks)
|
|
784
|
+
delete next[key];
|
|
785
|
+
return next;
|
|
786
|
+
}
|
|
787
|
+
var CONTRACTS_AMBIENT_ENVIRONMENT = Symbol.for("hasna:contracts:ambientClientEnvironment");
|
|
788
|
+
function isAmbientTodosEnv(env) {
|
|
789
|
+
if (typeof process !== "undefined" && env === process.env)
|
|
790
|
+
return true;
|
|
791
|
+
return env[CONTRACTS_AMBIENT_ENVIRONMENT] === true;
|
|
792
|
+
}
|
|
793
|
+
function todosResolverInputs(env, credentials = {}) {
|
|
794
|
+
const normalised = todosResolverEnv(env);
|
|
795
|
+
if (normalised === env)
|
|
796
|
+
return { env: normalised, credentials };
|
|
797
|
+
const keychain = { ...credentials.keychain };
|
|
798
|
+
if (keychain.enabled === undefined && keychain.run === undefined) {
|
|
799
|
+
keychain.enabled = isAmbientTodosEnv(env);
|
|
800
|
+
}
|
|
801
|
+
return { env: normalised, credentials: { ...credentials, keychain } };
|
|
802
|
+
}
|
|
803
|
+
|
|
804
|
+
// src/sdk/resolve.ts
|
|
805
|
+
var TODOS_LOCAL_SERVE_URL = "http://localhost:19427";
|
|
806
|
+
var localNoticePrinted = false;
|
|
807
|
+
function __resetTodosSdkLocalNotice() {
|
|
808
|
+
localNoticePrinted = false;
|
|
809
|
+
}
|
|
810
|
+
function stripV1(baseUrl) {
|
|
811
|
+
return baseUrl.replace(/\/+$/, "").replace(/\/v1$/, "");
|
|
812
|
+
}
|
|
813
|
+
function announceLocal(notice, reason) {
|
|
814
|
+
if (localNoticePrinted)
|
|
815
|
+
return;
|
|
816
|
+
localNoticePrinted = true;
|
|
817
|
+
const line = `todos: LOCAL mode \u2014 no Hasna credential resolved (${reason}); reading and writing the local ` + `todos-serve at ${TODOS_LOCAL_SERVE_URL}, not the hosted fleet. Set HASNA_TODOS_API_KEY, add the ` + `Keychain item hasna.credentials.todos.api-key, or write ~/.hasna/todos/config/credentials to go hosted.`;
|
|
818
|
+
if (notice)
|
|
819
|
+
notice(line);
|
|
820
|
+
else if (typeof process !== "undefined")
|
|
821
|
+
process.stderr.write(`${line}
|
|
822
|
+
`);
|
|
823
|
+
}
|
|
824
|
+
function resolveTodosSdkTransport(options = {}) {
|
|
825
|
+
const rawEnv = options.env ?? (typeof process !== "undefined" ? process.env : {});
|
|
826
|
+
const requestedCredentials = {
|
|
827
|
+
...options.credentials,
|
|
828
|
+
...options.apiKey !== undefined ? { apiKey: options.apiKey } : {}
|
|
829
|
+
};
|
|
830
|
+
const { env, credentials } = todosResolverInputs(rawEnv, requestedCredentials);
|
|
831
|
+
if (options.baseUrl) {
|
|
832
|
+
return {
|
|
833
|
+
mode: "http",
|
|
834
|
+
baseUrl: stripV1(options.baseUrl),
|
|
835
|
+
apiKey: options.apiKey ?? null,
|
|
836
|
+
apiKeySource: options.apiKey ? "explicit apiKey argument" : null,
|
|
837
|
+
apiUrlSource: "explicit baseUrl argument"
|
|
838
|
+
};
|
|
669
839
|
}
|
|
670
|
-
|
|
671
|
-
|
|
840
|
+
if (selectsTodosLocalStore(env)) {
|
|
841
|
+
announceLocal(options.notice, "HASNA_TODOS_LOCAL is set and nothing configures an authority");
|
|
842
|
+
return {
|
|
843
|
+
mode: "local-serve",
|
|
844
|
+
baseUrl: TODOS_LOCAL_SERVE_URL,
|
|
845
|
+
apiKey: options.apiKey ?? null,
|
|
846
|
+
apiKeySource: options.apiKey ? "explicit apiKey argument" : null,
|
|
847
|
+
apiUrlSource: "local-serve"
|
|
848
|
+
};
|
|
672
849
|
}
|
|
673
|
-
|
|
674
|
-
|
|
850
|
+
const credential = resolveCredential("todos", env, credentials);
|
|
851
|
+
const chainOptions = {
|
|
852
|
+
credentials: credential ? { ...credentials, apiKey: credential.apiKey } : credentials
|
|
853
|
+
};
|
|
854
|
+
let resolution;
|
|
855
|
+
try {
|
|
856
|
+
resolution = resolveClientTransport("todos", env, chainOptions);
|
|
857
|
+
} catch (error) {
|
|
858
|
+
if (error instanceof ClientTransportConfigurationError && /is not set and no API key could be resolved/.test(error.message)) {
|
|
859
|
+
announceLocal(options.notice, "nothing configured a Hasna Todos credential");
|
|
860
|
+
return {
|
|
861
|
+
mode: "local-serve",
|
|
862
|
+
baseUrl: TODOS_LOCAL_SERVE_URL,
|
|
863
|
+
apiKey: null,
|
|
864
|
+
apiKeySource: null,
|
|
865
|
+
apiUrlSource: "local-serve"
|
|
866
|
+
};
|
|
867
|
+
}
|
|
868
|
+
throw error;
|
|
675
869
|
}
|
|
676
|
-
|
|
677
|
-
|
|
870
|
+
return {
|
|
871
|
+
mode: "http",
|
|
872
|
+
baseUrl: stripV1(resolution.baseUrl),
|
|
873
|
+
apiKey: credential ? credential.apiKey : null,
|
|
874
|
+
apiKeySource: credential ? credential.source : resolution.apiKeySource,
|
|
875
|
+
apiUrlSource: resolution.apiUrlSource ?? "default"
|
|
876
|
+
};
|
|
877
|
+
}
|
|
878
|
+
function createTodosV1Client(options = {}) {
|
|
879
|
+
const resolved = resolveTodosSdkTransport(options);
|
|
880
|
+
if (resolved.mode !== "http" || !resolved.apiKey) {
|
|
881
|
+
throw new Error("TODOS_CREDENTIAL_MISSING: the /v1 client is hosted-only and no Hasna Todos credential resolved. " + "Looked at HASNA_TODOS_API_KEY_OVERRIDE / HASNA_PROFILE / HASNA_TODOS_API_KEY_REF, the Keychain item " + "hasna.credentials.todos.api-key, ~/.hasna/todos/config/credentials, then HASNA_TODOS_API_KEY.");
|
|
882
|
+
}
|
|
883
|
+
const baseFetch = options.fetch ?? ((input, init) => fetch(input, init));
|
|
884
|
+
const refreshOptions = { ...options, notice: () => {} };
|
|
885
|
+
const fetchWithFreshCredential = (input, init) => {
|
|
886
|
+
const headers = {};
|
|
887
|
+
new Headers(init?.headers ?? {}).forEach((value, key) => {
|
|
888
|
+
headers[key] = value;
|
|
889
|
+
});
|
|
890
|
+
try {
|
|
891
|
+
const fresh = resolveTodosSdkTransport(refreshOptions).apiKey;
|
|
892
|
+
if (fresh)
|
|
893
|
+
headers["x-api-key"] = fresh;
|
|
894
|
+
} catch {}
|
|
895
|
+
return baseFetch(input, { ...init, headers });
|
|
896
|
+
};
|
|
897
|
+
return new TodosV1Client({
|
|
898
|
+
baseUrl: resolved.baseUrl,
|
|
899
|
+
apiKey: resolved.apiKey,
|
|
900
|
+
fetch: fetchWithFreshCredential,
|
|
901
|
+
...options.headers ? { headers: options.headers } : {}
|
|
902
|
+
});
|
|
903
|
+
}
|
|
904
|
+
|
|
905
|
+
// src/sdk/client.ts
|
|
906
|
+
function buildQuery(params) {
|
|
907
|
+
const search = new URLSearchParams;
|
|
908
|
+
for (const [k, v] of Object.entries(params)) {
|
|
909
|
+
if (v !== undefined)
|
|
910
|
+
search.set(k, Array.isArray(v) ? v.join(",") : String(v));
|
|
678
911
|
}
|
|
679
|
-
|
|
680
|
-
|
|
912
|
+
const s = search.toString();
|
|
913
|
+
return s ? `?${s}` : "";
|
|
914
|
+
}
|
|
915
|
+
|
|
916
|
+
class TasksResource {
|
|
917
|
+
client;
|
|
918
|
+
constructor(client) {
|
|
919
|
+
this.client = client;
|
|
681
920
|
}
|
|
682
|
-
async
|
|
683
|
-
return this.
|
|
921
|
+
async list(options) {
|
|
922
|
+
return this.client._get("/api/tasks", buildQuery(options || {}));
|
|
684
923
|
}
|
|
685
|
-
async
|
|
686
|
-
return this.
|
|
924
|
+
async get(id, options) {
|
|
925
|
+
return this.client._get(`/api/tasks/${id}`, buildQuery(options || {}));
|
|
687
926
|
}
|
|
688
|
-
async
|
|
689
|
-
return this.
|
|
927
|
+
async getWithRelations(id) {
|
|
928
|
+
return this.client._get(`/api/tasks/${id}`, buildQuery({ format: "full" }));
|
|
690
929
|
}
|
|
691
|
-
async
|
|
692
|
-
|
|
930
|
+
async create(data) {
|
|
931
|
+
return this.client._post("/api/tasks", data);
|
|
693
932
|
}
|
|
694
|
-
async
|
|
695
|
-
return this.
|
|
933
|
+
async update(id, data) {
|
|
934
|
+
return this.client._patch(`/api/tasks/${id}`, data);
|
|
696
935
|
}
|
|
697
|
-
async
|
|
698
|
-
return this.
|
|
936
|
+
async delete(id) {
|
|
937
|
+
return this.client._delete(`/api/tasks/${id}`);
|
|
699
938
|
}
|
|
700
|
-
async
|
|
701
|
-
return this.
|
|
939
|
+
async start(id, agentId) {
|
|
940
|
+
return this.client._post(`/api/tasks/${id}/start`, { agent_id: agentId });
|
|
941
|
+
}
|
|
942
|
+
async complete(id, agentId) {
|
|
943
|
+
return this.client._post(`/api/tasks/${id}/complete`, { agent_id: agentId });
|
|
944
|
+
}
|
|
945
|
+
async fail(id, options) {
|
|
946
|
+
return this.client._post(`/api/tasks/${id}/fail`, options || {});
|
|
702
947
|
}
|
|
703
948
|
async logProgress(taskId, message, pctComplete, agentId) {
|
|
704
|
-
return this.
|
|
949
|
+
return this.client._post(`/api/tasks/${taskId}/progress`, {
|
|
950
|
+
message,
|
|
951
|
+
pct_complete: pctComplete,
|
|
952
|
+
agent_id: agentId
|
|
953
|
+
});
|
|
705
954
|
}
|
|
706
|
-
async
|
|
707
|
-
return this.
|
|
955
|
+
async getProgress(id, options) {
|
|
956
|
+
return this.client._get(`/api/tasks/${id}/progress`, buildQuery(options || {}));
|
|
708
957
|
}
|
|
709
|
-
async
|
|
710
|
-
|
|
711
|
-
return res.active;
|
|
958
|
+
async getHistory(id, options) {
|
|
959
|
+
return this.client._get(`/api/tasks/${id}/history`, buildQuery(options || {}));
|
|
712
960
|
}
|
|
713
|
-
async
|
|
714
|
-
return this.
|
|
961
|
+
async getAttachments(id) {
|
|
962
|
+
return this.client._get(`/api/tasks/${id}/attachments`);
|
|
715
963
|
}
|
|
716
|
-
async
|
|
717
|
-
return this.
|
|
964
|
+
async status(options) {
|
|
965
|
+
return this.client._get("/api/tasks/status", buildQuery(options || {}));
|
|
718
966
|
}
|
|
719
|
-
async
|
|
720
|
-
return this.
|
|
967
|
+
async next(options) {
|
|
968
|
+
return this.client._get("/api/tasks/next", buildQuery(options || {}));
|
|
721
969
|
}
|
|
722
|
-
async
|
|
723
|
-
return this.
|
|
970
|
+
async active(projectId) {
|
|
971
|
+
return this.client._get("/api/tasks/active", projectId ? `?project_id=${projectId}` : "");
|
|
724
972
|
}
|
|
725
|
-
async
|
|
726
|
-
return this.
|
|
973
|
+
async stale(options) {
|
|
974
|
+
return this.client._get("/api/tasks/stale", buildQuery(options || {}));
|
|
727
975
|
}
|
|
728
|
-
async
|
|
729
|
-
return this.
|
|
976
|
+
async changedSince(since, projectId, options) {
|
|
977
|
+
return this.client._get("/api/tasks/changed", buildQuery({ since, project_id: projectId, fields: options?.fields }));
|
|
730
978
|
}
|
|
731
|
-
async
|
|
732
|
-
|
|
979
|
+
async context(options) {
|
|
980
|
+
const q = buildQuery({
|
|
981
|
+
agent_id: options?.agentId,
|
|
982
|
+
project_id: options?.projectId,
|
|
983
|
+
format: options?.format,
|
|
984
|
+
fields: options?.fields
|
|
985
|
+
});
|
|
986
|
+
const url = `${this.client.baseUrl}/api/tasks/context${q}`;
|
|
987
|
+
const res = await this.client._fetchRaw(url);
|
|
988
|
+
if (!res.ok)
|
|
989
|
+
return options?.format === "json" ? {} : "";
|
|
990
|
+
if (options?.format === "json")
|
|
991
|
+
return res.json();
|
|
992
|
+
return res.text();
|
|
733
993
|
}
|
|
734
|
-
async
|
|
735
|
-
|
|
994
|
+
async export(options) {
|
|
995
|
+
const q = buildQuery(options || {});
|
|
996
|
+
const url = `${this.client.baseUrl}/api/tasks/export${q}`;
|
|
997
|
+
const res = await this.client._fetchRaw(url);
|
|
998
|
+
if (!res.ok)
|
|
999
|
+
throw new TodosAPIError("Export failed", res.status, res.statusText, null);
|
|
1000
|
+
if (options?.format === "csv")
|
|
1001
|
+
return res.text();
|
|
1002
|
+
return res.json();
|
|
736
1003
|
}
|
|
737
|
-
async
|
|
738
|
-
|
|
1004
|
+
async bulk(ids, action) {
|
|
1005
|
+
return this.client._post("/api/tasks/bulk", { ids, action });
|
|
739
1006
|
}
|
|
740
|
-
async
|
|
741
|
-
return this.
|
|
1007
|
+
async claim(agentId, projectId) {
|
|
1008
|
+
return this.client._post("/api/tasks/claim", { agent_id: agentId, project_id: projectId });
|
|
742
1009
|
}
|
|
743
|
-
}
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
1010
|
+
async* subscribe(options = {}) {
|
|
1011
|
+
const q = buildQuery({
|
|
1012
|
+
agent_id: options.agentId,
|
|
1013
|
+
project_id: options.projectId,
|
|
1014
|
+
events: options.events?.join(",")
|
|
1015
|
+
});
|
|
1016
|
+
const url = `${this.client.baseUrl}/api/tasks/stream${q}`;
|
|
1017
|
+
const resp = await this.client._fetchRaw(url);
|
|
1018
|
+
if (!resp.ok || !resp.body)
|
|
1019
|
+
throw new Error(`SSE connection failed: ${resp.status}`);
|
|
1020
|
+
const reader = resp.body.getReader();
|
|
1021
|
+
const decoder = new TextDecoder;
|
|
1022
|
+
let buffer = "";
|
|
1023
|
+
try {
|
|
1024
|
+
while (true) {
|
|
1025
|
+
const { done, value } = await reader.read();
|
|
1026
|
+
if (done)
|
|
1027
|
+
break;
|
|
1028
|
+
buffer += decoder.decode(value, { stream: true });
|
|
1029
|
+
const lines = buffer.split(`
|
|
1030
|
+
`);
|
|
1031
|
+
buffer = lines.pop() || "";
|
|
1032
|
+
for (const line of lines) {
|
|
1033
|
+
if (line.startsWith("data: ")) {
|
|
1034
|
+
try {
|
|
1035
|
+
const data = JSON.parse(line.slice(6));
|
|
1036
|
+
if (data.type !== "connected")
|
|
1037
|
+
yield data;
|
|
1038
|
+
} catch {}
|
|
1039
|
+
}
|
|
1040
|
+
}
|
|
1041
|
+
}
|
|
1042
|
+
} finally {
|
|
1043
|
+
reader.releaseLock();
|
|
1044
|
+
}
|
|
756
1045
|
}
|
|
757
1046
|
}
|
|
758
1047
|
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
"target_id",
|
|
764
|
-
"source_receipt_id",
|
|
765
|
-
"accepted_receipt_id",
|
|
766
|
-
"source_outcome",
|
|
767
|
-
"created_at",
|
|
768
|
-
"current_revision",
|
|
769
|
-
"accepted_result_digest"
|
|
770
|
-
];
|
|
771
|
-
function isRecord(value) {
|
|
772
|
-
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
773
|
-
}
|
|
774
|
-
function isNonEmptyString(value) {
|
|
775
|
-
return typeof value === "string" && value.length > 0;
|
|
776
|
-
}
|
|
777
|
-
function hasExactKeys(value, expected) {
|
|
778
|
-
const actual = Object.keys(value).sort();
|
|
779
|
-
const wanted = [...expected].sort();
|
|
780
|
-
return actual.length === wanted.length && actual.every((key, index) => key === wanted[index]);
|
|
781
|
-
}
|
|
782
|
-
function adoptionRejected(message) {
|
|
783
|
-
throw new TodosProjectRegistrationError("TODOS_PROJECT_REGISTRATION_ADOPTION_REJECTED", `TODOS_PROJECT_REGISTRATION_ADOPTION_REJECTED: ${message}`);
|
|
784
|
-
}
|
|
785
|
-
function assertTodosPriorRegistrationAdoptionValidationEnvelope(value, input) {
|
|
786
|
-
if (!isRecord(input) || !hasExactKeys(input, [
|
|
787
|
-
"source_request",
|
|
788
|
-
"source_receipt",
|
|
789
|
-
"current_record"
|
|
790
|
-
])) {
|
|
791
|
-
adoptionRejected("prior-adoption validation input is incomplete");
|
|
1048
|
+
class AgentsResource {
|
|
1049
|
+
client;
|
|
1050
|
+
constructor(client) {
|
|
1051
|
+
this.client = client;
|
|
792
1052
|
}
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
const current = input["current_record"];
|
|
796
|
-
if (!isRecord(request) || !isRecord(receipt) || !isRecord(current)) {
|
|
797
|
-
adoptionRejected("prior-adoption validation input records are incomplete");
|
|
1053
|
+
async list(options) {
|
|
1054
|
+
return this.client._get("/api/agents", buildQuery(options || {}));
|
|
798
1055
|
}
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
const acceptedReceiptId = sourceOutcome === "accepted" ? receipt["receipt_id"] : sourceOutcome === "duplicate_of_accepted" ? receipt["duplicate_of_receipt_id"] : null;
|
|
802
|
-
if (resourceKind !== "project" && resourceKind !== "task_list" || request["direction"] !== "forward" || sourceOutcome !== "accepted" && sourceOutcome !== "duplicate_of_accepted" || !isNonEmptyString(acceptedReceiptId) || !isNonEmptyString(receipt["receipt_id"]) || !isNonEmptyString(receipt["target_id"]) || !isNonEmptyString(receipt["result_revision"]) || !isNonEmptyString(receipt["result_digest"]) || !isNonEmptyString(current["id"]) || !isNonEmptyString(current["created_at"]) || !isNonEmptyString(current["updated_at"]) || receipt["authority"] !== "todos" || receipt["route"] !== request["authority_route"] || receipt["package_version"] !== request["package_version"] || receipt["authority_id"] !== request["authority_id"] || receipt["tenant_id"] !== request["tenant_id"] || receipt["corpus_id"] !== request["corpus_id"] || receipt["operation_id"] !== request["operation_id"] || receipt["step_id"] !== request["step_id"] || receipt["resource_kind"] !== resourceKind || receipt["direction"] !== "forward" || receipt["idempotency_key"] !== request["idempotency_key"] || receipt["request_digest"] !== request["request_digest"] || receipt["precondition_digest"] !== request["precondition_digest"] || receipt["accepted_receipt_id"] !== null || receipt["target_id"] !== current["id"] || receipt["result_revision"] !== current["created_at"]) {
|
|
803
|
-
adoptionRejected("prior-adoption validation input does not carry one complete accepted receipt and current target incarnation");
|
|
1056
|
+
async register(data) {
|
|
1057
|
+
return this.client._post("/api/agents", data);
|
|
804
1058
|
}
|
|
805
|
-
|
|
806
|
-
|
|
1059
|
+
async fullRegister(data) {
|
|
1060
|
+
return this.client._post("/api/agents", data);
|
|
807
1061
|
}
|
|
808
|
-
|
|
809
|
-
|
|
1062
|
+
async update(id, data) {
|
|
1063
|
+
return this.client._patch(`/api/agents/${id}`, data);
|
|
810
1064
|
}
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
1065
|
+
async delete(id) {
|
|
1066
|
+
return this.client._delete(`/api/agents/${id}`);
|
|
1067
|
+
}
|
|
1068
|
+
async bulkDelete(ids) {
|
|
1069
|
+
return this.client._post("/api/agents/bulk", { ids, action: "delete" });
|
|
1070
|
+
}
|
|
1071
|
+
async me(name) {
|
|
1072
|
+
return this.client._get("/api/agents/me", `?name=${encodeURIComponent(name)}`);
|
|
1073
|
+
}
|
|
1074
|
+
async queue(agentId) {
|
|
1075
|
+
return this.client._get(`/api/agents/${encodeURIComponent(agentId)}/queue`);
|
|
1076
|
+
}
|
|
1077
|
+
async team(agentId) {
|
|
1078
|
+
return this.client._get(`/api/agents/${encodeURIComponent(agentId)}/team`);
|
|
1079
|
+
}
|
|
1080
|
+
async orgChart() {
|
|
1081
|
+
return this.client._get("/api/org");
|
|
814
1082
|
}
|
|
815
|
-
return validation;
|
|
816
1083
|
}
|
|
817
1084
|
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
this.
|
|
825
|
-
|
|
826
|
-
|
|
1085
|
+
class ProjectsResource {
|
|
1086
|
+
client;
|
|
1087
|
+
constructor(client) {
|
|
1088
|
+
this.client = client;
|
|
1089
|
+
}
|
|
1090
|
+
async list(options) {
|
|
1091
|
+
return this.client._get("/api/projects", buildQuery(options || {}));
|
|
1092
|
+
}
|
|
1093
|
+
async create(data) {
|
|
1094
|
+
return this.client._post("/api/projects", data);
|
|
1095
|
+
}
|
|
1096
|
+
async delete(id) {
|
|
1097
|
+
return this.client._delete(`/api/projects/${id}`);
|
|
1098
|
+
}
|
|
1099
|
+
async bulkDelete(ids) {
|
|
1100
|
+
return this.client._post("/api/projects/bulk", { ids, action: "delete" });
|
|
827
1101
|
}
|
|
828
1102
|
}
|
|
829
1103
|
|
|
830
|
-
class
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
baseHeaders;
|
|
835
|
-
constructor(options) {
|
|
836
|
-
if (!options.baseUrl)
|
|
837
|
-
throw new Error("TodosV1Client requires a baseUrl.");
|
|
838
|
-
this.baseUrl = options.baseUrl.replace(/\/$/, "");
|
|
839
|
-
this.apiKey = options.apiKey;
|
|
840
|
-
this.fetchImpl = options.fetch ?? globalThis.fetch;
|
|
841
|
-
this.baseHeaders = options.headers ?? {};
|
|
1104
|
+
class PlansResource {
|
|
1105
|
+
client;
|
|
1106
|
+
constructor(client) {
|
|
1107
|
+
this.client = client;
|
|
842
1108
|
}
|
|
843
|
-
async
|
|
844
|
-
|
|
845
|
-
if (opts.query) {
|
|
846
|
-
for (const [key, value] of Object.entries(opts.query)) {
|
|
847
|
-
if (value !== undefined && value !== null)
|
|
848
|
-
url.searchParams.set(key, String(value));
|
|
849
|
-
}
|
|
850
|
-
}
|
|
851
|
-
const headers = { Accept: "application/json", ...this.baseHeaders, ...opts.init?.headers };
|
|
852
|
-
if (this.apiKey)
|
|
853
|
-
headers["x-api-key"] = this.apiKey;
|
|
854
|
-
let payload;
|
|
855
|
-
if (opts.body !== undefined) {
|
|
856
|
-
headers["Content-Type"] = "application/json";
|
|
857
|
-
payload = JSON.stringify(opts.body);
|
|
858
|
-
}
|
|
859
|
-
const response = await this.fetchImpl(url.toString(), { ...opts.init, method, headers, body: payload });
|
|
860
|
-
const text = await response.text();
|
|
861
|
-
const data = text ? (() => {
|
|
862
|
-
try {
|
|
863
|
-
return JSON.parse(text);
|
|
864
|
-
} catch {
|
|
865
|
-
return text;
|
|
866
|
-
}
|
|
867
|
-
})() : undefined;
|
|
868
|
-
if (!response.ok) {
|
|
869
|
-
throw new ApiError(response.status, `${method} ${path} failed: ${response.status}`, data);
|
|
870
|
-
}
|
|
871
|
-
return data;
|
|
872
|
-
}
|
|
873
|
-
async importSnapshot(body, init) {
|
|
874
|
-
return this.request("POST", `/v1/import`, {
|
|
875
|
-
body,
|
|
876
|
-
query: undefined,
|
|
877
|
-
init
|
|
878
|
-
});
|
|
879
|
-
}
|
|
880
|
-
async listPlans(query, init) {
|
|
881
|
-
return this.request("GET", `/v1/plans`, {
|
|
882
|
-
body: undefined,
|
|
883
|
-
query,
|
|
884
|
-
init
|
|
885
|
-
});
|
|
886
|
-
}
|
|
887
|
-
async createPlan(body, init) {
|
|
888
|
-
return this.request("POST", `/v1/plans`, {
|
|
889
|
-
body,
|
|
890
|
-
query: undefined,
|
|
891
|
-
init
|
|
892
|
-
});
|
|
893
|
-
}
|
|
894
|
-
async getPlan(id, init) {
|
|
895
|
-
return this.request("GET", `/v1/plans/${encodeURIComponent(String(id))}`, {
|
|
896
|
-
body: undefined,
|
|
897
|
-
query: undefined,
|
|
898
|
-
init
|
|
899
|
-
});
|
|
1109
|
+
async list(projectId) {
|
|
1110
|
+
return this.client._get("/api/plans", projectId ? `?project_id=${projectId}` : "");
|
|
900
1111
|
}
|
|
901
|
-
async
|
|
902
|
-
return this.
|
|
903
|
-
body: undefined,
|
|
904
|
-
query: undefined,
|
|
905
|
-
init
|
|
906
|
-
});
|
|
1112
|
+
async create(data) {
|
|
1113
|
+
return this.client._post("/api/plans", data);
|
|
907
1114
|
}
|
|
908
|
-
async
|
|
909
|
-
return this.
|
|
910
|
-
body,
|
|
911
|
-
query: undefined,
|
|
912
|
-
init
|
|
913
|
-
});
|
|
1115
|
+
async get(id) {
|
|
1116
|
+
return this.client._get(`/api/plans/${id}`);
|
|
914
1117
|
}
|
|
915
|
-
async
|
|
916
|
-
return this.
|
|
917
|
-
body: undefined,
|
|
918
|
-
query,
|
|
919
|
-
init
|
|
920
|
-
});
|
|
1118
|
+
async update(id, data) {
|
|
1119
|
+
return this.client._patch(`/api/plans/${id}`, data);
|
|
921
1120
|
}
|
|
922
|
-
async
|
|
923
|
-
return this.
|
|
924
|
-
body,
|
|
925
|
-
query: undefined,
|
|
926
|
-
init
|
|
927
|
-
});
|
|
1121
|
+
async delete(id) {
|
|
1122
|
+
return this.client._delete(`/api/plans/${id}`);
|
|
928
1123
|
}
|
|
929
|
-
async
|
|
930
|
-
return this.
|
|
931
|
-
body,
|
|
932
|
-
query: undefined,
|
|
933
|
-
init
|
|
934
|
-
});
|
|
1124
|
+
async bulkDelete(ids) {
|
|
1125
|
+
return this.client._post("/api/plans/bulk", { ids, action: "delete" });
|
|
935
1126
|
}
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
1127
|
+
}
|
|
1128
|
+
|
|
1129
|
+
class OrgsResource {
|
|
1130
|
+
client;
|
|
1131
|
+
constructor(client) {
|
|
1132
|
+
this.client = client;
|
|
942
1133
|
}
|
|
943
|
-
async
|
|
944
|
-
return this.
|
|
945
|
-
body: undefined,
|
|
946
|
-
query: undefined,
|
|
947
|
-
init
|
|
948
|
-
});
|
|
1134
|
+
async list() {
|
|
1135
|
+
return this.client._get("/api/orgs");
|
|
949
1136
|
}
|
|
950
|
-
async
|
|
951
|
-
return this.
|
|
952
|
-
body: undefined,
|
|
953
|
-
query,
|
|
954
|
-
init
|
|
955
|
-
});
|
|
1137
|
+
async create(data) {
|
|
1138
|
+
return this.client._post("/api/orgs", data);
|
|
956
1139
|
}
|
|
957
|
-
async
|
|
958
|
-
return this.
|
|
959
|
-
body,
|
|
960
|
-
query: undefined,
|
|
961
|
-
init
|
|
962
|
-
});
|
|
1140
|
+
async update(id, data) {
|
|
1141
|
+
return this.client._patch(`/api/orgs/${id}`, data);
|
|
963
1142
|
}
|
|
964
|
-
async
|
|
965
|
-
return this.
|
|
966
|
-
body,
|
|
967
|
-
query: undefined,
|
|
968
|
-
init
|
|
969
|
-
});
|
|
1143
|
+
async delete(id) {
|
|
1144
|
+
return this.client._delete(`/api/orgs/${id}`);
|
|
970
1145
|
}
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
1146
|
+
}
|
|
1147
|
+
|
|
1148
|
+
class WebhooksResource {
|
|
1149
|
+
client;
|
|
1150
|
+
constructor(client) {
|
|
1151
|
+
this.client = client;
|
|
977
1152
|
}
|
|
978
|
-
async
|
|
979
|
-
return this.
|
|
980
|
-
body,
|
|
981
|
-
query: undefined,
|
|
982
|
-
init
|
|
983
|
-
});
|
|
1153
|
+
async list() {
|
|
1154
|
+
return this.client._get("/api/webhooks");
|
|
984
1155
|
}
|
|
985
|
-
async
|
|
986
|
-
return this.
|
|
987
|
-
body,
|
|
988
|
-
query: undefined,
|
|
989
|
-
init
|
|
990
|
-
});
|
|
1156
|
+
async create(data) {
|
|
1157
|
+
return this.client._post("/api/webhooks", data);
|
|
991
1158
|
}
|
|
992
|
-
async
|
|
993
|
-
return this.
|
|
994
|
-
body,
|
|
995
|
-
query: undefined,
|
|
996
|
-
init
|
|
997
|
-
});
|
|
1159
|
+
async delete(id) {
|
|
1160
|
+
return this.client._delete(`/api/webhooks/${id}`);
|
|
998
1161
|
}
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1162
|
+
}
|
|
1163
|
+
|
|
1164
|
+
class TemplatesResource {
|
|
1165
|
+
client;
|
|
1166
|
+
constructor(client) {
|
|
1167
|
+
this.client = client;
|
|
1005
1168
|
}
|
|
1006
|
-
async
|
|
1007
|
-
return this.
|
|
1008
|
-
body: undefined,
|
|
1009
|
-
query,
|
|
1010
|
-
init
|
|
1011
|
-
});
|
|
1169
|
+
async list() {
|
|
1170
|
+
return this.client._get("/api/templates");
|
|
1012
1171
|
}
|
|
1013
|
-
async
|
|
1014
|
-
|
|
1015
|
-
body,
|
|
1016
|
-
query: undefined,
|
|
1017
|
-
init
|
|
1018
|
-
});
|
|
1019
|
-
return {
|
|
1020
|
-
validation: assertTodosPriorRegistrationAdoptionValidationEnvelope(response, body)
|
|
1021
|
-
};
|
|
1172
|
+
async create(data) {
|
|
1173
|
+
return this.client._post("/api/templates", data);
|
|
1022
1174
|
}
|
|
1023
|
-
async
|
|
1024
|
-
return this.
|
|
1025
|
-
body,
|
|
1026
|
-
query: undefined,
|
|
1027
|
-
init
|
|
1028
|
-
});
|
|
1175
|
+
async delete(id) {
|
|
1176
|
+
return this.client._delete(`/api/templates/${id}`);
|
|
1029
1177
|
}
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1178
|
+
}
|
|
1179
|
+
|
|
1180
|
+
class PrGroupsResource {
|
|
1181
|
+
client;
|
|
1182
|
+
constructor(client) {
|
|
1183
|
+
this.client = client;
|
|
1036
1184
|
}
|
|
1037
|
-
async
|
|
1038
|
-
return this.
|
|
1039
|
-
body,
|
|
1040
|
-
query: undefined,
|
|
1041
|
-
init
|
|
1042
|
-
});
|
|
1185
|
+
async admit(input) {
|
|
1186
|
+
return this.client._post("/api/pr-groups/admit", input);
|
|
1043
1187
|
}
|
|
1044
|
-
async
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
query: undefined,
|
|
1048
|
-
init
|
|
1049
|
-
});
|
|
1188
|
+
async get(groupId) {
|
|
1189
|
+
const result = await this.client._get(`/api/pr-groups/${encodeURIComponent(groupId)}`);
|
|
1190
|
+
return result.view;
|
|
1050
1191
|
}
|
|
1051
|
-
async
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1192
|
+
async events(groupId, options = {}) {
|
|
1193
|
+
const result = await this.client._get(`/api/pr-groups/${encodeURIComponent(groupId)}/events`, buildQuery({
|
|
1194
|
+
limit: options.limit,
|
|
1195
|
+
after_sequence: options.after_sequence
|
|
1196
|
+
}));
|
|
1197
|
+
return result.history;
|
|
1057
1198
|
}
|
|
1058
|
-
async
|
|
1059
|
-
return this.
|
|
1060
|
-
body,
|
|
1061
|
-
query: undefined,
|
|
1062
|
-
init
|
|
1063
|
-
});
|
|
1199
|
+
async append(input) {
|
|
1200
|
+
return this.client._post(`/api/pr-groups/${encodeURIComponent(input.group_id)}/events`, input);
|
|
1064
1201
|
}
|
|
1065
|
-
async
|
|
1066
|
-
return this.
|
|
1067
|
-
body,
|
|
1068
|
-
query: undefined,
|
|
1069
|
-
init
|
|
1070
|
-
});
|
|
1202
|
+
async recover(input) {
|
|
1203
|
+
return this.client._post(`/api/pr-groups/${encodeURIComponent(input.group_id)}/recover`, input);
|
|
1071
1204
|
}
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1205
|
+
}
|
|
1206
|
+
|
|
1207
|
+
class TodosClient {
|
|
1208
|
+
baseUrl;
|
|
1209
|
+
timeout;
|
|
1210
|
+
maxRetries;
|
|
1211
|
+
retryDelay;
|
|
1212
|
+
explicitApiKey;
|
|
1213
|
+
constructedApiKey;
|
|
1214
|
+
pinnedAuthority;
|
|
1215
|
+
tasks;
|
|
1216
|
+
agents;
|
|
1217
|
+
projects;
|
|
1218
|
+
plans;
|
|
1219
|
+
orgs;
|
|
1220
|
+
webhooks;
|
|
1221
|
+
templates;
|
|
1222
|
+
prGroups;
|
|
1223
|
+
constructor(options = {}) {
|
|
1224
|
+
const resolved = resolveTodosSdkTransport({
|
|
1225
|
+
...options.baseUrl !== undefined ? { baseUrl: options.baseUrl } : {},
|
|
1226
|
+
...options.apiKey !== undefined ? { apiKey: options.apiKey } : {}
|
|
1077
1227
|
});
|
|
1228
|
+
this.baseUrl = resolved.baseUrl;
|
|
1229
|
+
this.timeout = options.timeout ?? 1e4;
|
|
1230
|
+
this.explicitApiKey = options.apiKey;
|
|
1231
|
+
this.constructedApiKey = resolved.apiKey;
|
|
1232
|
+
this.pinnedAuthority = Boolean(options.baseUrl);
|
|
1233
|
+
this.maxRetries = options.maxRetries ?? 0;
|
|
1234
|
+
this.retryDelay = options.retryDelay ?? 1000;
|
|
1235
|
+
this.tasks = new TasksResource(this);
|
|
1236
|
+
this.agents = new AgentsResource(this);
|
|
1237
|
+
this.projects = new ProjectsResource(this);
|
|
1238
|
+
this.plans = new PlansResource(this);
|
|
1239
|
+
this.orgs = new OrgsResource(this);
|
|
1240
|
+
this.webhooks = new WebhooksResource(this);
|
|
1241
|
+
this.templates = new TemplatesResource(this);
|
|
1242
|
+
this.prGroups = new PrGroupsResource(this);
|
|
1078
1243
|
}
|
|
1079
|
-
|
|
1080
|
-
return
|
|
1081
|
-
body,
|
|
1082
|
-
query: undefined,
|
|
1083
|
-
init
|
|
1084
|
-
});
|
|
1244
|
+
static fromEnv(apiKey) {
|
|
1245
|
+
return new TodosClient(apiKey === undefined ? {} : { apiKey });
|
|
1085
1246
|
}
|
|
1086
|
-
async
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
init
|
|
1091
|
-
|
|
1247
|
+
async _fetchRaw(url, init) {
|
|
1248
|
+
const controller = new AbortController;
|
|
1249
|
+
const timer = setTimeout(() => controller.abort(), this.timeout);
|
|
1250
|
+
try {
|
|
1251
|
+
const headers = this._buildHeaders(init?.headers);
|
|
1252
|
+
return await fetch(url, { ...init, headers, signal: controller.signal });
|
|
1253
|
+
} finally {
|
|
1254
|
+
clearTimeout(timer);
|
|
1255
|
+
}
|
|
1092
1256
|
}
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1257
|
+
currentApiKey() {
|
|
1258
|
+
if (this.explicitApiKey !== undefined)
|
|
1259
|
+
return this.explicitApiKey;
|
|
1260
|
+
if (this.pinnedAuthority)
|
|
1261
|
+
return this.constructedApiKey;
|
|
1262
|
+
try {
|
|
1263
|
+
const fresh = resolveTodosSdkTransport({ notice: () => {} }).apiKey;
|
|
1264
|
+
if (fresh)
|
|
1265
|
+
return fresh;
|
|
1266
|
+
} catch {}
|
|
1267
|
+
return this.constructedApiKey;
|
|
1099
1268
|
}
|
|
1100
|
-
|
|
1101
|
-
return this.
|
|
1102
|
-
body: undefined,
|
|
1103
|
-
query: undefined,
|
|
1104
|
-
init
|
|
1105
|
-
});
|
|
1269
|
+
get apiKey() {
|
|
1270
|
+
return this.currentApiKey();
|
|
1106
1271
|
}
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1272
|
+
_buildHeaders(existing) {
|
|
1273
|
+
const headers = { "Content-Type": "application/json" };
|
|
1274
|
+
const apiKey = this.currentApiKey();
|
|
1275
|
+
if (apiKey)
|
|
1276
|
+
headers["x-api-key"] = apiKey;
|
|
1277
|
+
if (existing) {
|
|
1278
|
+
if (existing instanceof Headers) {
|
|
1279
|
+
existing.forEach((v, k) => {
|
|
1280
|
+
headers[k] = v;
|
|
1281
|
+
});
|
|
1282
|
+
} else if (Array.isArray(existing)) {
|
|
1283
|
+
for (const [k, v] of existing)
|
|
1284
|
+
headers[k] = v;
|
|
1285
|
+
} else {
|
|
1286
|
+
Object.assign(headers, existing);
|
|
1287
|
+
}
|
|
1288
|
+
}
|
|
1289
|
+
return headers;
|
|
1113
1290
|
}
|
|
1114
|
-
async
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1291
|
+
async _fetchWithRetry(path, init) {
|
|
1292
|
+
let lastError = null;
|
|
1293
|
+
const maxAttempts = this.maxRetries + 1;
|
|
1294
|
+
for (let attempt = 0;attempt < maxAttempts; attempt++) {
|
|
1295
|
+
try {
|
|
1296
|
+
return await this._fetch(path, init);
|
|
1297
|
+
} catch (e) {
|
|
1298
|
+
lastError = e;
|
|
1299
|
+
if (e instanceof TodosAPIError && e.status < 500 && e.status !== 429)
|
|
1300
|
+
throw e;
|
|
1301
|
+
if (e instanceof TodosUnauthorizedError || e instanceof TodosNotFoundError || e instanceof TodosConflictError)
|
|
1302
|
+
throw e;
|
|
1303
|
+
if (attempt < maxAttempts - 1) {
|
|
1304
|
+
const delay = this.retryDelay * Math.pow(2, attempt);
|
|
1305
|
+
if (e instanceof TodosRateLimitError) {
|
|
1306
|
+
await this._sleep(e.retryAfter * 1000);
|
|
1307
|
+
} else {
|
|
1308
|
+
await this._sleep(delay);
|
|
1309
|
+
}
|
|
1310
|
+
}
|
|
1311
|
+
}
|
|
1312
|
+
}
|
|
1313
|
+
throw lastError || new Error("Request failed after retries");
|
|
1120
1314
|
}
|
|
1121
|
-
async
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1315
|
+
async _fetch(path, init) {
|
|
1316
|
+
const controller = new AbortController;
|
|
1317
|
+
const timer = setTimeout(() => controller.abort(), this.timeout);
|
|
1318
|
+
try {
|
|
1319
|
+
const url = `${this.baseUrl}${path}`;
|
|
1320
|
+
const headers = this._buildHeaders(init?.headers);
|
|
1321
|
+
const res = await fetch(url, { ...init, headers, signal: controller.signal });
|
|
1322
|
+
if (!res.ok) {
|
|
1323
|
+
const body = await res.json().catch(() => ({ error: res.statusText }));
|
|
1324
|
+
const message = body.error || `HTTP ${res.status}: ${res.statusText}`;
|
|
1325
|
+
if (res.status === 401)
|
|
1326
|
+
throw new TodosUnauthorizedError(message, body);
|
|
1327
|
+
if (res.status === 404)
|
|
1328
|
+
throw new TodosNotFoundError(message, body);
|
|
1329
|
+
if (res.status === 409)
|
|
1330
|
+
throw new TodosConflictError(message, body);
|
|
1331
|
+
if (res.status === 429) {
|
|
1332
|
+
const retryAfter = parseInt(res.headers.get("retry-after") || "60", 10);
|
|
1333
|
+
throw new TodosRateLimitError(message, retryAfter, body);
|
|
1334
|
+
}
|
|
1335
|
+
throw new TodosAPIError(message, res.status, res.statusText, body);
|
|
1336
|
+
}
|
|
1337
|
+
if (res.status === 204)
|
|
1338
|
+
return null;
|
|
1339
|
+
const text = await res.text();
|
|
1340
|
+
if (text.length === 0)
|
|
1341
|
+
return null;
|
|
1342
|
+
return JSON.parse(text);
|
|
1343
|
+
} catch (e) {
|
|
1344
|
+
if (e instanceof DOMException && e.name === "AbortError") {
|
|
1345
|
+
throw new TodosTimeoutError(this.timeout);
|
|
1346
|
+
}
|
|
1347
|
+
throw e;
|
|
1348
|
+
} finally {
|
|
1349
|
+
clearTimeout(timer);
|
|
1350
|
+
}
|
|
1127
1351
|
}
|
|
1128
|
-
async
|
|
1129
|
-
return this.
|
|
1130
|
-
body: undefined,
|
|
1131
|
-
query: undefined,
|
|
1132
|
-
init
|
|
1133
|
-
});
|
|
1352
|
+
async _get(path, query = "") {
|
|
1353
|
+
return this._fetchWithRetry(`${path}${query}`);
|
|
1134
1354
|
}
|
|
1135
|
-
async
|
|
1136
|
-
return this.
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
init
|
|
1355
|
+
async _post(path, body) {
|
|
1356
|
+
return this._fetchWithRetry(path, {
|
|
1357
|
+
method: "POST",
|
|
1358
|
+
body: body ? JSON.stringify(body) : undefined
|
|
1140
1359
|
});
|
|
1141
1360
|
}
|
|
1142
|
-
async
|
|
1143
|
-
return this.
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
init
|
|
1361
|
+
async _patch(path, body) {
|
|
1362
|
+
return this._fetchWithRetry(path, {
|
|
1363
|
+
method: "PATCH",
|
|
1364
|
+
body: JSON.stringify(body)
|
|
1147
1365
|
});
|
|
1148
1366
|
}
|
|
1149
|
-
async
|
|
1150
|
-
return this.
|
|
1151
|
-
body,
|
|
1152
|
-
query: undefined,
|
|
1153
|
-
init
|
|
1154
|
-
});
|
|
1367
|
+
async _delete(path) {
|
|
1368
|
+
return this._fetchWithRetry(path, { method: "DELETE" });
|
|
1155
1369
|
}
|
|
1156
|
-
|
|
1157
|
-
return
|
|
1158
|
-
body: undefined,
|
|
1159
|
-
query: undefined,
|
|
1160
|
-
init
|
|
1161
|
-
});
|
|
1370
|
+
_sleep(ms) {
|
|
1371
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
1162
1372
|
}
|
|
1163
|
-
async
|
|
1164
|
-
return this.
|
|
1165
|
-
body,
|
|
1166
|
-
query: undefined,
|
|
1167
|
-
init
|
|
1168
|
-
});
|
|
1373
|
+
async getHealth() {
|
|
1374
|
+
return this._get("/api/health");
|
|
1169
1375
|
}
|
|
1170
|
-
async
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1376
|
+
async isAlive() {
|
|
1377
|
+
try {
|
|
1378
|
+
await this._get("/api/stats");
|
|
1379
|
+
return true;
|
|
1380
|
+
} catch {
|
|
1381
|
+
return false;
|
|
1382
|
+
}
|
|
1176
1383
|
}
|
|
1177
|
-
async
|
|
1178
|
-
return this.
|
|
1179
|
-
body,
|
|
1180
|
-
query: undefined,
|
|
1181
|
-
init
|
|
1182
|
-
});
|
|
1384
|
+
async getStats() {
|
|
1385
|
+
return this._get("/api/stats");
|
|
1183
1386
|
}
|
|
1184
|
-
async
|
|
1185
|
-
return this.
|
|
1186
|
-
body: undefined,
|
|
1187
|
-
query: undefined,
|
|
1188
|
-
init
|
|
1189
|
-
});
|
|
1387
|
+
async getReport(options) {
|
|
1388
|
+
return this._get("/api/report", buildQuery({ days: options?.days, project_id: options?.projectId }));
|
|
1190
1389
|
}
|
|
1191
|
-
async
|
|
1192
|
-
return this.
|
|
1193
|
-
body,
|
|
1194
|
-
query: undefined,
|
|
1195
|
-
init
|
|
1196
|
-
});
|
|
1390
|
+
async doctor() {
|
|
1391
|
+
return this._get("/api/doctor");
|
|
1197
1392
|
}
|
|
1198
|
-
async
|
|
1199
|
-
return this.
|
|
1200
|
-
body,
|
|
1201
|
-
query: undefined,
|
|
1202
|
-
init
|
|
1203
|
-
});
|
|
1393
|
+
async activity(limit) {
|
|
1394
|
+
return this._get("/api/activity", limit ? `?limit=${limit}` : "");
|
|
1204
1395
|
}
|
|
1205
|
-
async
|
|
1206
|
-
return this.
|
|
1207
|
-
body,
|
|
1208
|
-
query: undefined,
|
|
1209
|
-
init
|
|
1210
|
-
});
|
|
1396
|
+
async listTasks(filter = {}) {
|
|
1397
|
+
return this.tasks.list(filter);
|
|
1211
1398
|
}
|
|
1212
|
-
async
|
|
1213
|
-
return this.
|
|
1214
|
-
body: undefined,
|
|
1215
|
-
query,
|
|
1216
|
-
init
|
|
1217
|
-
});
|
|
1399
|
+
async getTask(id, options) {
|
|
1400
|
+
return this.tasks.get(id, options);
|
|
1218
1401
|
}
|
|
1219
|
-
async createTask(
|
|
1220
|
-
return this.
|
|
1221
|
-
body,
|
|
1222
|
-
query: undefined,
|
|
1223
|
-
init
|
|
1224
|
-
});
|
|
1402
|
+
async createTask(data) {
|
|
1403
|
+
return this.tasks.create(data);
|
|
1225
1404
|
}
|
|
1226
|
-
async
|
|
1227
|
-
return this.
|
|
1228
|
-
body: undefined,
|
|
1229
|
-
query: undefined,
|
|
1230
|
-
init
|
|
1231
|
-
});
|
|
1405
|
+
async updateTask(id, data) {
|
|
1406
|
+
return this.tasks.update(id, data);
|
|
1232
1407
|
}
|
|
1233
|
-
async deleteTask(id
|
|
1234
|
-
|
|
1235
|
-
body: undefined,
|
|
1236
|
-
query: undefined,
|
|
1237
|
-
init
|
|
1238
|
-
});
|
|
1408
|
+
async deleteTask(id) {
|
|
1409
|
+
await this.tasks.delete(id);
|
|
1239
1410
|
}
|
|
1240
|
-
async
|
|
1241
|
-
return this.
|
|
1242
|
-
body,
|
|
1243
|
-
query: undefined,
|
|
1244
|
-
init
|
|
1245
|
-
});
|
|
1411
|
+
async startTask(id, agentId) {
|
|
1412
|
+
return this.tasks.start(id, agentId);
|
|
1246
1413
|
}
|
|
1247
|
-
async
|
|
1248
|
-
return this.
|
|
1249
|
-
body: undefined,
|
|
1250
|
-
query,
|
|
1251
|
-
init
|
|
1252
|
-
});
|
|
1414
|
+
async completeTask(id, agentId) {
|
|
1415
|
+
return this.tasks.complete(id, agentId);
|
|
1253
1416
|
}
|
|
1254
|
-
async
|
|
1255
|
-
return this.
|
|
1256
|
-
body,
|
|
1257
|
-
query: undefined,
|
|
1258
|
-
init
|
|
1259
|
-
});
|
|
1417
|
+
async failTask(id, options = {}) {
|
|
1418
|
+
return this.tasks.fail(id, options);
|
|
1260
1419
|
}
|
|
1261
|
-
async
|
|
1262
|
-
return this.
|
|
1263
|
-
body,
|
|
1264
|
-
query: undefined,
|
|
1265
|
-
init
|
|
1266
|
-
});
|
|
1420
|
+
async logProgress(taskId, message, pctComplete, agentId) {
|
|
1421
|
+
return this.tasks.logProgress(taskId, message, pctComplete, agentId);
|
|
1267
1422
|
}
|
|
1268
|
-
async
|
|
1269
|
-
return this.
|
|
1270
|
-
body,
|
|
1271
|
-
query: undefined,
|
|
1272
|
-
init
|
|
1273
|
-
});
|
|
1423
|
+
async getStatus(projectId, agentId) {
|
|
1424
|
+
return this.tasks.status({ project_id: projectId, agent_id: agentId });
|
|
1274
1425
|
}
|
|
1275
|
-
async
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
query: undefined,
|
|
1279
|
-
init
|
|
1280
|
-
});
|
|
1426
|
+
async getActiveWork(projectId) {
|
|
1427
|
+
const res = await this.tasks.active(projectId);
|
|
1428
|
+
return res.active;
|
|
1281
1429
|
}
|
|
1282
|
-
async
|
|
1283
|
-
return this.
|
|
1284
|
-
body,
|
|
1285
|
-
query: undefined,
|
|
1286
|
-
init
|
|
1287
|
-
});
|
|
1430
|
+
async getTasksChangedSince(since, projectId) {
|
|
1431
|
+
return this.tasks.changedSince(since, projectId);
|
|
1288
1432
|
}
|
|
1289
|
-
async
|
|
1290
|
-
return this.
|
|
1291
|
-
body,
|
|
1292
|
-
query: undefined,
|
|
1293
|
-
init
|
|
1294
|
-
});
|
|
1433
|
+
async getStaleTasks(minutes, projectId) {
|
|
1434
|
+
return this.tasks.stale({ minutes, project_id: projectId });
|
|
1295
1435
|
}
|
|
1296
|
-
async
|
|
1297
|
-
return this.
|
|
1298
|
-
body: undefined,
|
|
1299
|
-
query: undefined,
|
|
1300
|
-
init
|
|
1301
|
-
});
|
|
1436
|
+
async getContext(options = {}) {
|
|
1437
|
+
return this.tasks.context(options);
|
|
1302
1438
|
}
|
|
1303
|
-
async
|
|
1304
|
-
return this.
|
|
1305
|
-
body: undefined,
|
|
1306
|
-
query,
|
|
1307
|
-
init
|
|
1308
|
-
});
|
|
1439
|
+
async exportTasks(filter = {}) {
|
|
1440
|
+
return this.tasks.export(filter);
|
|
1309
1441
|
}
|
|
1310
|
-
async
|
|
1311
|
-
return this.
|
|
1312
|
-
body,
|
|
1313
|
-
query: undefined,
|
|
1314
|
-
init
|
|
1315
|
-
});
|
|
1442
|
+
async claimNextTask(agentId, projectId) {
|
|
1443
|
+
return this.tasks.claim(agentId, projectId);
|
|
1316
1444
|
}
|
|
1317
|
-
async
|
|
1318
|
-
return this.
|
|
1319
|
-
body: undefined,
|
|
1320
|
-
query: undefined,
|
|
1321
|
-
init
|
|
1322
|
-
});
|
|
1445
|
+
async getTaskHistory(id, options) {
|
|
1446
|
+
return this.tasks.getHistory(id, options);
|
|
1323
1447
|
}
|
|
1324
|
-
async
|
|
1325
|
-
return this.
|
|
1326
|
-
body: undefined,
|
|
1327
|
-
query: undefined,
|
|
1328
|
-
init
|
|
1329
|
-
});
|
|
1448
|
+
async getTaskAttachments(id) {
|
|
1449
|
+
return this.tasks.getAttachments(id);
|
|
1330
1450
|
}
|
|
1331
|
-
async
|
|
1332
|
-
return this.
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1451
|
+
async getTaskProgress(id, options) {
|
|
1452
|
+
return this.tasks.getProgress(id, options);
|
|
1453
|
+
}
|
|
1454
|
+
async* subscribeToStream(options = {}) {
|
|
1455
|
+
yield* this.tasks.subscribe(options);
|
|
1456
|
+
}
|
|
1457
|
+
async getProjects() {
|
|
1458
|
+
return this.projects.list();
|
|
1337
1459
|
}
|
|
1338
1460
|
}
|
|
1461
|
+
function createClient(options) {
|
|
1462
|
+
return new TodosClient(options);
|
|
1463
|
+
}
|
|
1339
1464
|
export {
|
|
1465
|
+
resolveTodosSdkTransport,
|
|
1466
|
+
createTodosV1Client,
|
|
1340
1467
|
createClient,
|
|
1468
|
+
__resetTodosSdkLocalNotice,
|
|
1341
1469
|
TodosV1Client,
|
|
1342
1470
|
ApiError as TodosV1ApiError,
|
|
1343
1471
|
TodosUnauthorizedError,
|
|
@@ -1346,5 +1474,6 @@ export {
|
|
|
1346
1474
|
TodosNotFoundError,
|
|
1347
1475
|
TodosConflictError,
|
|
1348
1476
|
TodosClient,
|
|
1349
|
-
TodosAPIError
|
|
1477
|
+
TodosAPIError,
|
|
1478
|
+
TODOS_LOCAL_SERVE_URL
|
|
1350
1479
|
};
|