harvask-cli 0.4.0 → 0.6.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/README.md +36 -3
- package/dist/api-client.js +23 -9
- package/dist/api-client.js.map +1 -1
- package/dist/commands/attachment/index.js +11 -1
- package/dist/commands/attachment/index.js.map +1 -1
- package/dist/commands/project/builds.js +13 -9
- package/dist/commands/project/builds.js.map +1 -1
- package/dist/commands/project/index.js +2 -1
- package/dist/commands/project/index.js.map +1 -1
- package/dist/commands/scheduled-task/index.js +290 -47
- package/dist/commands/scheduled-task/index.js.map +1 -1
- package/dist/commands/storage/index.js +17 -1
- package/dist/commands/storage/index.js.map +1 -1
- package/dist/commands/workspace/batch.js +65 -0
- package/dist/commands/workspace/batch.js.map +1 -0
- package/dist/commands/workspace/collect.js +368 -0
- package/dist/commands/workspace/collect.js.map +1 -0
- package/dist/commands/workspace/index.js +240 -0
- package/dist/commands/workspace/index.js.map +1 -0
- package/dist/errors/hint-map.js +34 -0
- package/dist/errors/hint-map.js.map +1 -1
- package/dist/registry.js +2 -0
- package/dist/registry.js.map +1 -1
- package/dist/utils/upload.js +29 -0
- package/dist/utils/upload.js.map +1 -1
- package/package.json +1 -1
- package/skills/harvask/AGENTS.md +18 -2
- package/skills/harvask/GEMINI.md +18 -2
- package/skills/harvask/SKILL.md +18 -2
- package/skills/harvask/migration.md +72 -0
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* workspace カテゴリ(AI ワークスペース, /v1/projects/{project}/workspace)。
|
|
3
|
+
*
|
|
4
|
+
* ローカルにある既存プロジェクトを、プロジェクトの AI ワークスペース
|
|
5
|
+
* (Web の Files タブ=AI セッションの `~/work`)へまとめて投入する。
|
|
6
|
+
* 契約の正本は project-management-tool の docs/features/workspace-file-api.md。
|
|
7
|
+
*
|
|
8
|
+
* ここだけ他カテゴリと形が違う(ApiCall を 1 本返すのではなく、preflight → 複数バッチの
|
|
9
|
+
* multipart POST という手順になる)。判定はすべて collect.ts / batch.ts の純粋関数に寄せ、
|
|
10
|
+
* このファイルは手順と出力の組み立てに徹する。
|
|
11
|
+
*/
|
|
12
|
+
import { resolve } from 'node:path';
|
|
13
|
+
import { statSync } from 'node:fs';
|
|
14
|
+
import { parseProjectArg, requireConfirmation } from '../_exec.js';
|
|
15
|
+
import { resolveProjectId } from '../../utils/project-resolver.js';
|
|
16
|
+
import { printOutput } from '../../output/index.js';
|
|
17
|
+
import { ValidationError } from '../../errors/index.js';
|
|
18
|
+
import { parseIntArg } from '../../utils/input.js';
|
|
19
|
+
import { buildFilesFormData } from '../../utils/upload.js';
|
|
20
|
+
import { API_NS } from '../../api-base.js';
|
|
21
|
+
import { collectFiles, detectProtectedPaths, joinWorkspacePath, normalizeDestPath, shouldAbortForInvalid, } from './collect.js';
|
|
22
|
+
import { chunk, DEFAULT_MAX_BATCH_BYTES, MAX_FILE_BYTES, MAX_PREFLIGHT_PATHS, partitionOversized, planBatches, totalBytes, } from './batch.js';
|
|
23
|
+
/** `post_max_size`(1GB)。--max-batch-bytes をこれ以上にしても 413 になるだけ。 */
|
|
24
|
+
const POST_MAX_SIZE = 1024 * 1024 * 1024;
|
|
25
|
+
/** 出力に載せるサンプル件数(全部出すと数千行になるため)。 */
|
|
26
|
+
const SAMPLE_LIMIT = 10;
|
|
27
|
+
function collectRepeatable(value, previous) {
|
|
28
|
+
return previous.concat([value]);
|
|
29
|
+
}
|
|
30
|
+
function sample(items) {
|
|
31
|
+
const head = items.slice(0, SAMPLE_LIMIT).join(', ');
|
|
32
|
+
return items.length > SAMPLE_LIMIT ? `${head}, … (+${items.length - SAMPLE_LIMIT} more)` : head;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* バッチのサイズからリクエストタイムアウトを決める。
|
|
36
|
+
* 既定の 120 秒固定では 100MB 級のバッチが上り帯域次第で必ず落ちる(しかもリトライで倍払う)。
|
|
37
|
+
*/
|
|
38
|
+
function timeoutForBytes(bytes) {
|
|
39
|
+
const megabytes = Math.ceil(bytes / (1024 * 1024));
|
|
40
|
+
return Math.min(120_000 + megabytes * 2_000, 900_000);
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* preflight を MAX_PREFLIGHT_PATHS 件ずつ投げて結果をまとめる。
|
|
44
|
+
*/
|
|
45
|
+
async function preflightAll(client, projectId, paths, dest) {
|
|
46
|
+
const merged = {
|
|
47
|
+
conflicts: [],
|
|
48
|
+
blocked: [],
|
|
49
|
+
invalid: [],
|
|
50
|
+
blocked_extensions: [],
|
|
51
|
+
};
|
|
52
|
+
for (const part of chunk(paths, MAX_PREFLIGHT_PATHS)) {
|
|
53
|
+
const body = { paths: part };
|
|
54
|
+
if (dest !== '') {
|
|
55
|
+
body.path = dest;
|
|
56
|
+
}
|
|
57
|
+
const res = await client.post(`${API_NS}/projects/${projectId}/workspace/upload/preflight`, body);
|
|
58
|
+
merged.conflicts.push(...(res.conflicts ?? []));
|
|
59
|
+
merged.blocked.push(...(res.blocked ?? []));
|
|
60
|
+
merged.invalid.push(...(res.invalid ?? []));
|
|
61
|
+
if (merged.blocked_extensions.length === 0) {
|
|
62
|
+
merged.blocked_extensions = res.blocked_extensions ?? [];
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return merged;
|
|
66
|
+
}
|
|
67
|
+
export const workspaceModule = {
|
|
68
|
+
name: 'workspace',
|
|
69
|
+
describe: 'AI workspace (push a local directory into the project workspace)',
|
|
70
|
+
register(program, ctx) {
|
|
71
|
+
const ws = program
|
|
72
|
+
.command('workspace')
|
|
73
|
+
.description('AI workspace (Files tab / ~/work in AI sessions)');
|
|
74
|
+
ws.command('push')
|
|
75
|
+
.description('Push a local directory into the project AI workspace')
|
|
76
|
+
.argument('<dir>', 'local directory to push')
|
|
77
|
+
.option('-p, --project <key|id>', 'project key (PRJ) or numeric id')
|
|
78
|
+
.option('--dest <path>', 'destination directory inside the workspace (default: root)')
|
|
79
|
+
.option('--dry-run', 'preflight only: print the plan and send no bytes')
|
|
80
|
+
.option('--include-ignored', 'ignore .gitignore and the default excludes (.env* stays excluded)')
|
|
81
|
+
.option('--exclude <glob>', 'additional exclude (repeatable)', collectRepeatable, [])
|
|
82
|
+
.option('--include <glob>', 'restore a default-excluded path (repeatable)', collectRepeatable, [])
|
|
83
|
+
.option('--force', 'allow pushing into apps/ or canvas/')
|
|
84
|
+
.option('--max-batch-bytes <n>', 'max total bytes per request (default 200MB)', parseIntArg)
|
|
85
|
+
.option('--yes', 'approve overwrites in non-interactive mode')
|
|
86
|
+
.addHelpText('after', `
|
|
87
|
+
Sends a local tree to the project workspace (Web: Files tab, AI sessions: ~/work).
|
|
88
|
+
Same relative path = overwrite; there is no version history. Always --dry-run first.
|
|
89
|
+
|
|
90
|
+
harvask workspace push ./legacy-app -p PRJ --dest legacy --dry-run
|
|
91
|
+
harvask workspace push ./legacy-app -p PRJ --dest legacy
|
|
92
|
+
|
|
93
|
+
Excluded no matter what: .env* and .git/ (the workspace is visible to every member).
|
|
94
|
+
Excluded by default (--include-ignored / --include <glob> to restore):
|
|
95
|
+
node_modules/ vendor/ dist/ build/ __pycache__/ .venv/ .DS_Store
|
|
96
|
+
In a git repository, .gitignore decides the rest.
|
|
97
|
+
|
|
98
|
+
Windows binaries (.exe .bat .cmd .ps1 .vbs .com .msi .dll) cannot be stored: they
|
|
99
|
+
are reported under "skipped", not treated as an error. .sh is allowed.
|
|
100
|
+
|
|
101
|
+
Batches are not atomic. If it fails partway, the result JSON lists "remaining";
|
|
102
|
+
re-running the same command resumes (re-uploading overwrites).
|
|
103
|
+
A live mini-app / browser-agent session makes this fail with 409 — end the
|
|
104
|
+
session instead of retrying, or the upload is silently rolled back.
|
|
105
|
+
`)
|
|
106
|
+
.action(async (dirArg, opts) => {
|
|
107
|
+
const root = resolve(dirArg);
|
|
108
|
+
let rootStat;
|
|
109
|
+
try {
|
|
110
|
+
rootStat = statSync(root);
|
|
111
|
+
}
|
|
112
|
+
catch (e) {
|
|
113
|
+
throw new ValidationError(`Directory not found or unreadable: ${root} (${e.message})`);
|
|
114
|
+
}
|
|
115
|
+
if (!rootStat.isDirectory()) {
|
|
116
|
+
throw new ValidationError(`Not a directory: ${root}`);
|
|
117
|
+
}
|
|
118
|
+
const dest = normalizeDestPath(opts.dest);
|
|
119
|
+
const maxBatchBytes = opts.maxBatchBytes ?? DEFAULT_MAX_BATCH_BYTES;
|
|
120
|
+
if (maxBatchBytes < 1 || maxBatchBytes > POST_MAX_SIZE) {
|
|
121
|
+
throw new ValidationError(`--max-batch-bytes must be between 1 and ${POST_MAX_SIZE} (post_max_size)`);
|
|
122
|
+
}
|
|
123
|
+
// 1. ローカルを集める(ネットワークより先に。引数の誤りはここで落とす)
|
|
124
|
+
const collected = collectFiles(root, {
|
|
125
|
+
includeIgnored: Boolean(opts.includeIgnored),
|
|
126
|
+
exclude: opts.exclude,
|
|
127
|
+
include: opts.include,
|
|
128
|
+
});
|
|
129
|
+
const sized = partitionOversized(collected.files);
|
|
130
|
+
const excluded = [
|
|
131
|
+
...collected.excluded,
|
|
132
|
+
...sized.oversized.map((f) => ({
|
|
133
|
+
path: f.path,
|
|
134
|
+
reason: 'too_large',
|
|
135
|
+
detail: `${f.size} bytes > ${MAX_FILE_BYTES} (per-file limit)`,
|
|
136
|
+
})),
|
|
137
|
+
];
|
|
138
|
+
const client = ctx.getApiClient();
|
|
139
|
+
const projectId = await resolveProjectId(client, parseProjectArg(opts.project) ?? {});
|
|
140
|
+
if (sized.ok.length === 0) {
|
|
141
|
+
printOutput({
|
|
142
|
+
project_id: projectId,
|
|
143
|
+
dest,
|
|
144
|
+
source: collected.source,
|
|
145
|
+
planned: 0,
|
|
146
|
+
uploaded: 0,
|
|
147
|
+
overwritten: 0,
|
|
148
|
+
skipped: [],
|
|
149
|
+
excluded,
|
|
150
|
+
batches: { total: 0, completed: 0 },
|
|
151
|
+
remaining: [],
|
|
152
|
+
note: 'nothing to push (everything was excluded or the directory is empty)',
|
|
153
|
+
}, ctx.out);
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
// 2. preflight(何が上書きになり、何が置けないか)
|
|
157
|
+
const pre = await preflightAll(client, projectId, sized.ok.map((f) => f.path), dest);
|
|
158
|
+
if (shouldAbortForInvalid(pre.invalid)) {
|
|
159
|
+
// 1 件でも不正なパスがあると upload は丸ごと 422 になる。部分的には送らない。
|
|
160
|
+
throw new ValidationError(`${pre.invalid.length} path(s) cannot be stored in the workspace: ${sample(pre.invalid)}`);
|
|
161
|
+
}
|
|
162
|
+
const blocked = new Set(pre.blocked.map((b) => b.path));
|
|
163
|
+
const files = sized.ok.filter((f) => !blocked.has(f.path));
|
|
164
|
+
const skipped = pre.blocked.map((b) => ({
|
|
165
|
+
path: b.path,
|
|
166
|
+
reason: 'blocked_extension',
|
|
167
|
+
extension: b.extension,
|
|
168
|
+
}));
|
|
169
|
+
const protectedHits = detectProtectedPaths(files.map((f) => joinWorkspacePath(dest, f.path)));
|
|
170
|
+
if (protectedHits.length > 0 && !opts.force) {
|
|
171
|
+
throw new ValidationError(`${protectedHits.length} path(s) would land under apps/ or canvas/, where mini-app sources, their SQLite data and Canvas documents live: ${sample(protectedHits)}. Use a different --dest, or --force if you really mean it.`);
|
|
172
|
+
}
|
|
173
|
+
const conflicts = new Set(pre.conflicts);
|
|
174
|
+
const willOverwrite = files.filter((f) => conflicts.has(f.path)).length;
|
|
175
|
+
const batches = planBatches(files, { maxBytes: maxBatchBytes });
|
|
176
|
+
if (opts.dryRun) {
|
|
177
|
+
printOutput({
|
|
178
|
+
dry_run: true,
|
|
179
|
+
project_id: projectId,
|
|
180
|
+
dest,
|
|
181
|
+
source: collected.source,
|
|
182
|
+
planned: files.length,
|
|
183
|
+
would_create: files.length - willOverwrite,
|
|
184
|
+
would_overwrite: willOverwrite,
|
|
185
|
+
total_bytes: totalBytes(files),
|
|
186
|
+
batches: { total: batches.length },
|
|
187
|
+
protected: protectedHits,
|
|
188
|
+
skipped,
|
|
189
|
+
excluded,
|
|
190
|
+
}, ctx.out);
|
|
191
|
+
return;
|
|
192
|
+
}
|
|
193
|
+
// 上書きの承認は 1 バイトも送らない --dry-run の後で聞く(計画を見るのに --yes は要らない)
|
|
194
|
+
if (willOverwrite > 0) {
|
|
195
|
+
requireConfirmation(opts, `overwrite ${willOverwrite} existing workspace file(s)`);
|
|
196
|
+
}
|
|
197
|
+
// 3. 投入。バッチ間は原子的でないので、落ちたら未送信分を remaining に載せて終わる
|
|
198
|
+
// (同名は上書きなので、同じコマンドをもう一度流せばそこから再開になる)
|
|
199
|
+
const uploaded = [];
|
|
200
|
+
let overwritten = 0;
|
|
201
|
+
let completed = 0;
|
|
202
|
+
let remaining = files.map((f) => f.path);
|
|
203
|
+
const result = () => ({
|
|
204
|
+
project_id: projectId,
|
|
205
|
+
dest,
|
|
206
|
+
source: collected.source,
|
|
207
|
+
planned: files.length,
|
|
208
|
+
uploaded: uploaded.length,
|
|
209
|
+
overwritten,
|
|
210
|
+
skipped,
|
|
211
|
+
excluded,
|
|
212
|
+
batches: { total: batches.length, completed },
|
|
213
|
+
remaining,
|
|
214
|
+
});
|
|
215
|
+
try {
|
|
216
|
+
for (const batch of batches) {
|
|
217
|
+
const form = buildFilesFormData(batch, dest);
|
|
218
|
+
const res = await client.postMultipart(`${API_NS}/projects/${projectId}/workspace/upload`, form, { timeout: timeoutForBytes(totalBytes(batch)) });
|
|
219
|
+
completed++;
|
|
220
|
+
for (const item of res.uploaded ?? []) {
|
|
221
|
+
uploaded.push(item.path);
|
|
222
|
+
}
|
|
223
|
+
for (const item of res.skipped ?? []) {
|
|
224
|
+
skipped.push(item);
|
|
225
|
+
}
|
|
226
|
+
overwritten += batch.filter((f) => conflicts.has(f.path)).length;
|
|
227
|
+
const done = new Set(batch.map((f) => f.path));
|
|
228
|
+
remaining = remaining.filter((p) => !done.has(p));
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
catch (err) {
|
|
232
|
+
// 結果は stdout(再開に使う remaining を含む)、理由は stderr(Error/Why/Hint)
|
|
233
|
+
printOutput(result(), ctx.out);
|
|
234
|
+
throw err;
|
|
235
|
+
}
|
|
236
|
+
printOutput(result(), ctx.out);
|
|
237
|
+
});
|
|
238
|
+
},
|
|
239
|
+
};
|
|
240
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/commands/workspace/index.ts"],"names":[],"mappings":"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"}
|
package/dist/errors/hint-map.js
CHANGED
|
@@ -49,7 +49,41 @@ export function hintFor(e) {
|
|
|
49
49
|
why: apiMessage ?? 'Resource not found.',
|
|
50
50
|
hint: 'Verify the id/key (e.g. project key PRJ, issue key PRJ-123). Use `harvask project list` / `harvask issue search` to find valid ids.',
|
|
51
51
|
};
|
|
52
|
+
case 409:
|
|
53
|
+
if (code === 'workspace_session_active') {
|
|
54
|
+
return {
|
|
55
|
+
why: 'A mini-app / browser-agent session is live for this project; while it runs the workspace is synced from the session, so anything written now is silently rolled back.',
|
|
56
|
+
hint: 'End that session, then run the command again. Do not retry on a timer — this is a guard, not a transient error.',
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
return {
|
|
60
|
+
why: apiMessage ?? e.message,
|
|
61
|
+
hint: 'The resource is locked or was changed by someone else. Re-read the current state before trying again.',
|
|
62
|
+
};
|
|
63
|
+
case 413:
|
|
64
|
+
return {
|
|
65
|
+
why: apiMessage ?? 'Request body too large (HTTP 413).',
|
|
66
|
+
hint: 'Send less per request (e.g. `workspace push --max-batch-bytes 52428800`). Already-sent files are listed in the result; "remaining" shows what is left.',
|
|
67
|
+
};
|
|
52
68
|
case 422:
|
|
69
|
+
if (code === 'missing_chat_id') {
|
|
70
|
+
return {
|
|
71
|
+
why: 'chat_message attachments identify the chat with the X-Chat-Id header, not a body field.',
|
|
72
|
+
hint: 'Pass `--chat-id <id>` (find it with `harvask chat list`).',
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
if (code === 'handover_approval_required') {
|
|
76
|
+
return {
|
|
77
|
+
why: 'This was generated by a handover and is still waiting for a human to approve it.',
|
|
78
|
+
hint: 'Approve it in the handover review screen first. It cannot be activated or run from the CLI before that.',
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
if (code === 'cannot_overwrite_folder') {
|
|
82
|
+
return {
|
|
83
|
+
why: 'A folder with that name already exists in the target directory.',
|
|
84
|
+
hint: 'Rename the file, pick another --parent-id, or drop --on-conflict overwrite.',
|
|
85
|
+
};
|
|
86
|
+
}
|
|
53
87
|
return {
|
|
54
88
|
why: formatValidationErrors(e.apiError?.errors) ?? apiMessage ?? e.message,
|
|
55
89
|
hint: 'Fix the listed fields. See `--help` for allowed values (issue_type/priority enums, title<=255, content<=500000).',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hint-map.js","sourceRoot":"","sources":["../../src/errors/hint-map.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AASH,MAAM,UAAU,sBAAsB,CAAC,MAAiC;IACtE,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,OAAO,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC;SAC1B,GAAG,CAAC,CAAC,CAAC,KAAK,EAAE,QAAQ,CAAC,EAAE,EAAE,CAAC,GAAG,KAAK,KAAK,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;SAC9D,IAAI,CAAC,IAAI,CAAC,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,OAAO,CAAC,CAAiB;IACvC,MAAM,IAAI,GAAG,CAAC,CAAC,QAAQ,EAAE,IAAI,CAAC;IAC9B,MAAM,UAAU,GAAG,CAAC,CAAC,QAAQ,EAAE,OAAO,CAAC;IAEvC,QAAQ,CAAC,CAAC,UAAU,EAAE,CAAC;QACrB,KAAK,GAAG;YACN,OAAO;gBACL,GAAG,EAAE,UAAU,IAAI,2BAA2B;gBAC9C,IAAI,EAAE,gEAAgE;aACvE,CAAC;QACJ,KAAK,GAAG;YACN,IAAI,IAAI,KAAK,iBAAiB,EAAE,CAAC;gBAC/B,OAAO;oBACL,GAAG,EAAE,6CAA6C;oBAClD,IAAI,EAAE,uGAAuG;iBAC9G,CAAC;YACJ,CAAC;YACD,IAAI,IAAI,KAAK,oBAAoB,EAAE,CAAC;gBAClC,OAAO;oBACL,GAAG,EAAE,uCAAuC;oBAC5C,IAAI,EAAE,2FAA2F;iBAClG,CAAC;YACJ,CAAC;YACD,IAAI,IAAI,KAAK,oBAAoB,EAAE,CAAC;gBAClC,OAAO;oBACL,GAAG,EAAE,qDAAqD;oBAC1D,IAAI,EAAE,sEAAsE;iBAC7E,CAAC;YACJ,CAAC;YACD,OAAO;gBACL,GAAG,EAAE,UAAU,IAAI,gBAAgB;gBACnC,IAAI,EAAE,4FAA4F;aACnG,CAAC;QACJ,KAAK,GAAG;YACN,OAAO;gBACL,GAAG,EAAE,UAAU,IAAI,qBAAqB;gBACxC,IAAI,EAAE,qIAAqI;aAC5I,CAAC;QACJ,KAAK,GAAG;YACN,OAAO;gBACL,GAAG,EAAE,sBAAsB,CAAC,CAAC,CAAC,QAAQ,EAAE,MAAM,CAAC,IAAI,UAAU,IAAI,CAAC,CAAC,OAAO;gBAC1E,IAAI,EAAE,kHAAkH;aACzH,CAAC;QACJ,KAAK,GAAG;YACN,OAAO;gBACL,GAAG,EAAE,0BAA0B;gBAC/B,IAAI,EAAE,2FAA2F;aAClG,CAAC;QACJ,KAAK,GAAG,CAAC;QACT,KAAK,CAAC;YACJ,OAAO;gBACL,GAAG,EAAE,CAAC,CAAC,OAAO;gBACd,IAAI,EAAE,0FAA0F;aACjG,CAAC;QACJ;YACE,IAAI,CAAC,CAAC,UAAU,IAAI,GAAG,EAAE,CAAC;gBACxB,OAAO;oBACL,GAAG,EAAE,UAAU,IAAI,CAAC,CAAC,OAAO;oBAC5B,IAAI,EAAE,gGAAgG;iBACvG,CAAC;YACJ,CAAC;YACD,OAAO;gBACL,GAAG,EAAE,UAAU,IAAI,CAAC,CAAC,OAAO;gBAC5B,IAAI,EAAE,oFAAoF;aAC3F,CAAC;IACN,CAAC;AACH,CAAC"}
|
|
1
|
+
{"version":3,"file":"hint-map.js","sourceRoot":"","sources":["../../src/errors/hint-map.ts"],"names":[],"mappings":"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"}
|
package/dist/registry.js
CHANGED
|
@@ -21,6 +21,7 @@ import { scheduledTaskModule } from './commands/scheduled-task/index.js';
|
|
|
21
21
|
import { chatModule } from './commands/chat/index.js';
|
|
22
22
|
import { fileModule } from './commands/file/index.js';
|
|
23
23
|
import { storageModule } from './commands/storage/index.js';
|
|
24
|
+
import { workspaceModule } from './commands/workspace/index.js';
|
|
24
25
|
import { attachmentModule } from './commands/attachment/index.js';
|
|
25
26
|
import { skillModule } from './commands/skill/index.js';
|
|
26
27
|
export const CATEGORIES = [
|
|
@@ -38,6 +39,7 @@ export const CATEGORIES = [
|
|
|
38
39
|
chatModule,
|
|
39
40
|
fileModule,
|
|
40
41
|
storageModule,
|
|
42
|
+
workspaceModule,
|
|
41
43
|
attachmentModule,
|
|
42
44
|
siteCredentialModule,
|
|
43
45
|
previewConfigModule,
|
package/dist/registry.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AA4BH,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AACxD,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AACtD,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAC5D,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AACtD,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AACtD,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AACpD,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAC9D,OAAO,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAChE,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACnE,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AACtD,OAAO,EAAE,oBAAoB,EAAE,MAAM,qCAAqC,CAAC;AAC3E,OAAO,EAAE,mBAAmB,EAAE,MAAM,oCAAoC,CAAC;AACzE,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAC9D,OAAO,EAAE,mBAAmB,EAAE,MAAM,oCAAoC,CAAC;AACzE,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AACtD,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AACtD,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAC5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AAClE,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAExD,MAAM,CAAC,MAAM,UAAU,GAAqB;IAC1C,UAAU;IACV,aAAa;IACb,WAAW;IACX,UAAU;IACV,gBAAgB;IAChB,UAAU;IACV,eAAe;IACf,cAAc;IACd,UAAU;IACV,cAAc;IACd,mBAAmB;IACnB,UAAU;IACV,UAAU;IACV,aAAa;IACb,gBAAgB;IAChB,oBAAoB;IACpB,mBAAmB;IACnB,WAAW;IACX,SAAS;CACV,CAAC"}
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AA4BH,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AACxD,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AACtD,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAC5D,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AACtD,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AACtD,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AACpD,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAC9D,OAAO,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAChE,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACnE,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AACtD,OAAO,EAAE,oBAAoB,EAAE,MAAM,qCAAqC,CAAC;AAC3E,OAAO,EAAE,mBAAmB,EAAE,MAAM,oCAAoC,CAAC;AACzE,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAC9D,OAAO,EAAE,mBAAmB,EAAE,MAAM,oCAAoC,CAAC;AACzE,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AACtD,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AACtD,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAC5D,OAAO,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAChE,OAAO,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AAClE,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAExD,MAAM,CAAC,MAAM,UAAU,GAAqB;IAC1C,UAAU;IACV,aAAa;IACb,WAAW;IACX,UAAU;IACV,gBAAgB;IAChB,UAAU;IACV,eAAe;IACf,cAAc;IACd,UAAU;IACV,cAAc;IACd,mBAAmB;IACnB,UAAU;IACV,UAAU;IACV,aAAa;IACb,eAAe;IACf,gBAAgB;IAChB,oBAAoB;IACpB,mBAAmB;IACnB,WAAW;IACX,SAAS;CACV,CAAC"}
|
package/dist/utils/upload.js
CHANGED
|
@@ -29,4 +29,33 @@ export function buildFileFormData(filePath, fields = {}) {
|
|
|
29
29
|
}
|
|
30
30
|
return form;
|
|
31
31
|
}
|
|
32
|
+
/**
|
|
33
|
+
* 複数ファイルを `files[]` / `paths[]` として積む(workspace upload の API 仕様)。
|
|
34
|
+
*
|
|
35
|
+
* `paths[i]` はファイル名込みのフル相対パスで、`files[i]` と同順・同数でなければならない。
|
|
36
|
+
* 添付名は `basename(paths[i])` と一致させる(食い違うとサーバーが 422
|
|
37
|
+
* `path_filename_mismatch` を返す — 意図した場所に違う名前で置かれる事故を防ぐため)。
|
|
38
|
+
*
|
|
39
|
+
* @param basePath ワークスペース内のベースディレクトリ(空ならルート直下)
|
|
40
|
+
*/
|
|
41
|
+
export function buildFilesFormData(files, basePath = '') {
|
|
42
|
+
const form = new FormData();
|
|
43
|
+
for (const file of files) {
|
|
44
|
+
let buffer;
|
|
45
|
+
try {
|
|
46
|
+
buffer = readFileSync(file.absolute);
|
|
47
|
+
}
|
|
48
|
+
catch (e) {
|
|
49
|
+
throw new ValidationError(`File not found or unreadable: ${file.absolute} (${e.message})`);
|
|
50
|
+
}
|
|
51
|
+
const name = basename(file.path);
|
|
52
|
+
const blob = new Blob([new Uint8Array(buffer)], { type: getMimeType(name) });
|
|
53
|
+
form.append('files[]', blob, name);
|
|
54
|
+
form.append('paths[]', file.path);
|
|
55
|
+
}
|
|
56
|
+
if (basePath !== '') {
|
|
57
|
+
form.append('path', basePath);
|
|
58
|
+
}
|
|
59
|
+
return form;
|
|
60
|
+
}
|
|
32
61
|
//# sourceMappingURL=upload.js.map
|
package/dist/utils/upload.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"upload.js","sourceRoot":"","sources":["../../src/utils/upload.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AACrC,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAE9C;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAC/B,QAAgB,EAChB,SAAsD,EAAE;IAExD,IAAI,MAAc,CAAC;IACnB,IAAI,CAAC;QACH,MAAM,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAC;IAClC,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,MAAM,IAAI,eAAe,CAAC,iCAAiC,QAAQ,KAAM,CAAW,CAAC,OAAO,GAAG,CAAC,CAAC;IACnG,CAAC;IACD,MAAM,IAAI,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAChC,MAAM,IAAI,GAAG,IAAI,QAAQ,EAAE,CAAC;IAC5B,0EAA0E;IAC1E,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,CAAC,IAAI,UAAU,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC7E,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;IAChC,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAClD,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;YAC1C,IAAI,CAAC,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;QAClC,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}
|
|
1
|
+
{"version":3,"file":"upload.js","sourceRoot":"","sources":["../../src/utils/upload.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AACrC,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAE9C;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAC/B,QAAgB,EAChB,SAAsD,EAAE;IAExD,IAAI,MAAc,CAAC;IACnB,IAAI,CAAC;QACH,MAAM,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAC;IAClC,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,MAAM,IAAI,eAAe,CAAC,iCAAiC,QAAQ,KAAM,CAAW,CAAC,OAAO,GAAG,CAAC,CAAC;IACnG,CAAC;IACD,MAAM,IAAI,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAChC,MAAM,IAAI,GAAG,IAAI,QAAQ,EAAE,CAAC;IAC5B,0EAA0E;IAC1E,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,CAAC,IAAI,UAAU,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC7E,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;IAChC,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAClD,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;YAC1C,IAAI,CAAC,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;QAClC,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,kBAAkB,CAChC,KAAgD,EAChD,QAAQ,GAAG,EAAE;IAEb,MAAM,IAAI,GAAG,IAAI,QAAQ,EAAE,CAAC;IAC5B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,MAAc,CAAC;QACnB,IAAI,CAAC;YACH,MAAM,GAAG,YAAY,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACvC,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,MAAM,IAAI,eAAe,CACvB,iCAAiC,IAAI,CAAC,QAAQ,KAAM,CAAW,CAAC,OAAO,GAAG,CAC3E,CAAC;QACJ,CAAC;QACD,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACjC,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,CAAC,IAAI,UAAU,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAC7E,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;QACnC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;IACpC,CAAC;IACD,IAAI,QAAQ,KAAK,EAAE,EAAE,CAAC;QACpB,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IAChC,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}
|
package/package.json
CHANGED
package/skills/harvask/AGENTS.md
CHANGED
|
@@ -40,6 +40,12 @@ If a command fails with an auth error (exit code 3), run `harvask login` again.
|
|
|
40
40
|
harvask issue assign -p PRJ 1234 --assignee-id 42
|
|
41
41
|
```
|
|
42
42
|
|
|
43
|
+
## Migrating an existing project
|
|
44
|
+
|
|
45
|
+
Bringing a local directory (or another tool's export) into a harvask project has its own
|
|
46
|
+
rules — where files should go, what must never be uploaded, and why a live session blocks
|
|
47
|
+
writes. Read `migration.md` in this skill directory before pushing anything.
|
|
48
|
+
|
|
43
49
|
## project key vs id
|
|
44
50
|
|
|
45
51
|
- Humans know the **key** (e.g. `PRJ`); the API uses a numeric **id**.
|
|
@@ -127,9 +133,10 @@ harvask issue bulk-create | bulk-update (--items @file.json [--atomic])
|
|
|
127
133
|
harvask wiki list | show | create | update (--base-version required) | search | set-home | history | delete | bulk-create | bulk-update
|
|
128
134
|
harvask milestone list | create | update
|
|
129
135
|
harvask workflow list | show | create | update | execute (non-idempotent, --yes required non-interactively)
|
|
130
|
-
harvask scheduled-task list | show | create | update | delete
|
|
136
|
+
harvask scheduled-task list | show | create | update | execute (non-idempotent, --yes required non-interactively) | delete
|
|
131
137
|
harvask file search | stats
|
|
132
|
-
harvask storage list | search | stats | upload | folder | move | rename | delete | download | content
|
|
138
|
+
harvask storage list | search | stats | upload (--on-conflict rename|overwrite|error) | folder | move | rename | delete | download | content
|
|
139
|
+
harvask workspace push <dir> (--dest, --dry-run, --exclude) # local tree -> AI workspace
|
|
133
140
|
harvask preview-config show | update
|
|
134
141
|
harvask site-credential # list browser credentials
|
|
135
142
|
|
|
@@ -148,5 +155,14 @@ Notes:
|
|
|
148
155
|
- `personal-wiki` is intentionally not available via the CLI.
|
|
149
156
|
- File/binary: `storage upload` / `attachment upload` take `--file <path>`;
|
|
150
157
|
`storage download` / `attachment download` save with `--out <path>`.
|
|
158
|
+
`attachment upload --type chat_message` also needs `--chat-id <id>`.
|
|
159
|
+
- `project create --key` is optional; without it the server derives a unique key
|
|
160
|
+
from `--name`.
|
|
161
|
+
- `scheduled-task` has three execution types: `issue`, `workflow` and `chat`
|
|
162
|
+
(`--chat-message` is the body, required for chat). `update` changes only the
|
|
163
|
+
fields you pass, including the schedule (`--frequency` / `--time` /
|
|
164
|
+
`--day-of-week` / `--day-of-month` / `--cron`). Fields that do not belong to
|
|
165
|
+
the resulting execution type are rejected by the CLI, because the server
|
|
166
|
+
silently drops them.
|
|
151
167
|
|
|
152
168
|
Use `harvask <command> --help` for options, examples, and prerequisites.
|
package/skills/harvask/GEMINI.md
CHANGED
|
@@ -40,6 +40,12 @@ If a command fails with an auth error (exit code 3), run `harvask login` again.
|
|
|
40
40
|
harvask issue assign -p PRJ 1234 --assignee-id 42
|
|
41
41
|
```
|
|
42
42
|
|
|
43
|
+
## Migrating an existing project
|
|
44
|
+
|
|
45
|
+
Bringing a local directory (or another tool's export) into a harvask project has its own
|
|
46
|
+
rules — where files should go, what must never be uploaded, and why a live session blocks
|
|
47
|
+
writes. Read `migration.md` in this skill directory before pushing anything.
|
|
48
|
+
|
|
43
49
|
## project key vs id
|
|
44
50
|
|
|
45
51
|
- Humans know the **key** (e.g. `PRJ`); the API uses a numeric **id**.
|
|
@@ -127,9 +133,10 @@ harvask issue bulk-create | bulk-update (--items @file.json [--atomic])
|
|
|
127
133
|
harvask wiki list | show | create | update (--base-version required) | search | set-home | history | delete | bulk-create | bulk-update
|
|
128
134
|
harvask milestone list | create | update
|
|
129
135
|
harvask workflow list | show | create | update | execute (non-idempotent, --yes required non-interactively)
|
|
130
|
-
harvask scheduled-task list | show | create | update | delete
|
|
136
|
+
harvask scheduled-task list | show | create | update | execute (non-idempotent, --yes required non-interactively) | delete
|
|
131
137
|
harvask file search | stats
|
|
132
|
-
harvask storage list | search | stats | upload | folder | move | rename | delete | download | content
|
|
138
|
+
harvask storage list | search | stats | upload (--on-conflict rename|overwrite|error) | folder | move | rename | delete | download | content
|
|
139
|
+
harvask workspace push <dir> (--dest, --dry-run, --exclude) # local tree -> AI workspace
|
|
133
140
|
harvask preview-config show | update
|
|
134
141
|
harvask site-credential # list browser credentials
|
|
135
142
|
|
|
@@ -148,5 +155,14 @@ Notes:
|
|
|
148
155
|
- `personal-wiki` is intentionally not available via the CLI.
|
|
149
156
|
- File/binary: `storage upload` / `attachment upload` take `--file <path>`;
|
|
150
157
|
`storage download` / `attachment download` save with `--out <path>`.
|
|
158
|
+
`attachment upload --type chat_message` also needs `--chat-id <id>`.
|
|
159
|
+
- `project create --key` is optional; without it the server derives a unique key
|
|
160
|
+
from `--name`.
|
|
161
|
+
- `scheduled-task` has three execution types: `issue`, `workflow` and `chat`
|
|
162
|
+
(`--chat-message` is the body, required for chat). `update` changes only the
|
|
163
|
+
fields you pass, including the schedule (`--frequency` / `--time` /
|
|
164
|
+
`--day-of-week` / `--day-of-month` / `--cron`). Fields that do not belong to
|
|
165
|
+
the resulting execution type are rejected by the CLI, because the server
|
|
166
|
+
silently drops them.
|
|
151
167
|
|
|
152
168
|
Use `harvask <command> --help` for options, examples, and prerequisites.
|
package/skills/harvask/SKILL.md
CHANGED
|
@@ -43,6 +43,12 @@ If a command fails with an auth error (exit code 3), run `harvask login` again.
|
|
|
43
43
|
harvask issue assign -p PRJ 1234 --assignee-id 42
|
|
44
44
|
```
|
|
45
45
|
|
|
46
|
+
## Migrating an existing project
|
|
47
|
+
|
|
48
|
+
Bringing a local directory (or another tool's export) into a harvask project has its own
|
|
49
|
+
rules — where files should go, what must never be uploaded, and why a live session blocks
|
|
50
|
+
writes. Read `migration.md` in this skill directory before pushing anything.
|
|
51
|
+
|
|
46
52
|
## project key vs id
|
|
47
53
|
|
|
48
54
|
- Humans know the **key** (e.g. `PRJ`); the API uses a numeric **id**.
|
|
@@ -130,9 +136,10 @@ harvask issue bulk-create | bulk-update (--items @file.json [--atomic])
|
|
|
130
136
|
harvask wiki list | show | create | update (--base-version required) | search | set-home | history | delete | bulk-create | bulk-update
|
|
131
137
|
harvask milestone list | create | update
|
|
132
138
|
harvask workflow list | show | create | update | execute (non-idempotent, --yes required non-interactively)
|
|
133
|
-
harvask scheduled-task list | show | create | update | delete
|
|
139
|
+
harvask scheduled-task list | show | create | update | execute (non-idempotent, --yes required non-interactively) | delete
|
|
134
140
|
harvask file search | stats
|
|
135
|
-
harvask storage list | search | stats | upload | folder | move | rename | delete | download | content
|
|
141
|
+
harvask storage list | search | stats | upload (--on-conflict rename|overwrite|error) | folder | move | rename | delete | download | content
|
|
142
|
+
harvask workspace push <dir> (--dest, --dry-run, --exclude) # local tree -> AI workspace
|
|
136
143
|
harvask preview-config show | update
|
|
137
144
|
harvask site-credential # list browser credentials
|
|
138
145
|
|
|
@@ -151,5 +158,14 @@ Notes:
|
|
|
151
158
|
- `personal-wiki` is intentionally not available via the CLI.
|
|
152
159
|
- File/binary: `storage upload` / `attachment upload` take `--file <path>`;
|
|
153
160
|
`storage download` / `attachment download` save with `--out <path>`.
|
|
161
|
+
`attachment upload --type chat_message` also needs `--chat-id <id>`.
|
|
162
|
+
- `project create --key` is optional; without it the server derives a unique key
|
|
163
|
+
from `--name`.
|
|
164
|
+
- `scheduled-task` has three execution types: `issue`, `workflow` and `chat`
|
|
165
|
+
(`--chat-message` is the body, required for chat). `update` changes only the
|
|
166
|
+
fields you pass, including the schedule (`--frequency` / `--time` /
|
|
167
|
+
`--day-of-week` / `--day-of-month` / `--cron`). Fields that do not belong to
|
|
168
|
+
the resulting execution type are rejected by the CLI, because the server
|
|
169
|
+
silently drops them.
|
|
154
170
|
|
|
155
171
|
Use `harvask <command> --help` for options, examples, and prerequisites.
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# Migrating an existing local project into harvask
|
|
2
|
+
|
|
3
|
+
Use this when someone wants to bring a project that lives on their machine (or in another
|
|
4
|
+
tool) into a harvask project: source trees, design docs, spreadsheets, legacy assets.
|
|
5
|
+
|
|
6
|
+
## First: pick the destination. They are not interchangeable.
|
|
7
|
+
|
|
8
|
+
| What you have | Where it goes | How |
|
|
9
|
+
|---|---|---|
|
|
10
|
+
| Code in a git repository | **Keep it in git.** Link the repo in the project settings (Web UI: Settings > Repository) | No migration needed — AI sessions clone it |
|
|
11
|
+
| Files the AI should work on directly: docs, data, assets, legacy scripts, a non-git tree | **AI workspace** (Files tab = `~/work` in AI sessions) | `harvask workspace push` |
|
|
12
|
+
| Reference documents people will search and share | **Storage** | `harvask storage upload` |
|
|
13
|
+
| Knowledge that should be read, edited and versioned as text | **Wiki** | `harvask wiki create` / `global-wiki` |
|
|
14
|
+
|
|
15
|
+
If the answer is "code that is already in git", say so and stop — pushing a clone into the
|
|
16
|
+
workspace duplicates it and the copies drift apart.
|
|
17
|
+
|
|
18
|
+
## Workspace push
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
harvask workspace push ./legacy-app -p PRJ --dest legacy --dry-run # plan only, sends nothing
|
|
22
|
+
harvask workspace push ./legacy-app -p PRJ --dest legacy --yes # do it
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Always run `--dry-run` first and show the plan (`would_create` / `would_overwrite` /
|
|
26
|
+
`skipped` / `excluded`) before sending anything. Overwrites are silent and there is no
|
|
27
|
+
version history, so `--yes` is required to overwrite in a non-interactive shell.
|
|
28
|
+
|
|
29
|
+
### Rules that bite
|
|
30
|
+
|
|
31
|
+
- **Never push `.env` or credentials.** The CLI excludes `.env*` and cannot be told
|
|
32
|
+
otherwise, because the workspace is visible to every project member. If secrets are
|
|
33
|
+
needed by the AI, use project secrets (Web UI), not files.
|
|
34
|
+
- `.gitignore` is respected when the directory is a git repo (the CLI lets `git ls-files`
|
|
35
|
+
enumerate, so `.git/info/exclude` and your global gitignore count too). `node_modules/`,
|
|
36
|
+
`vendor/`, `dist/`, `build/`, `__pycache__/`, `.venv/`, `.DS_Store` are excluded by
|
|
37
|
+
default; `--include-ignored` (everything) or `--include <glob>` (one path) brings them
|
|
38
|
+
back. `--exclude <glob>` wins over `--include`.
|
|
39
|
+
- Windows binaries and scripts (`.exe .bat .cmd .ps1 .vbs .com .msi .dll`) cannot be
|
|
40
|
+
stored. They are reported as `skipped`, not treated as an error. `.sh` is allowed, but
|
|
41
|
+
the workspace has no execute bit — run it as `sh script.sh`.
|
|
42
|
+
- Do not push into `apps/` or `canvas/`. Mini-app sources plus their SQLite data and
|
|
43
|
+
Canvas documents live there; overwriting them breaks the running app. The CLI refuses
|
|
44
|
+
unless `--force`, and you should ask the user before reaching for it.
|
|
45
|
+
- Symlinks are not followed (reported as `excluded`), and empty directories are not
|
|
46
|
+
reproduced (object storage has no directories).
|
|
47
|
+
|
|
48
|
+
### When it stops
|
|
49
|
+
|
|
50
|
+
- **409 `workspace_session_active`** — a mini-app or browser-agent session is live for
|
|
51
|
+
that project. Do **not** retry: while a session runs, the workspace is synced from the
|
|
52
|
+
session and anything you upload is silently rolled back. End the session, then push.
|
|
53
|
+
- **Invalid paths** — the dry run reports them and the CLI refuses to send. Those paths
|
|
54
|
+
can never be stored (`..`, empty segments, deeper than 20 levels); one bad path fails a
|
|
55
|
+
whole request, so fix or drop them.
|
|
56
|
+
- **Partial failure** — batches are not atomic. The result JSON lists `remaining`; re-run
|
|
57
|
+
the same command to continue. Re-uploading is safe: same path = overwrite.
|
|
58
|
+
- **413 / timeouts** on a slow link — send less per request with
|
|
59
|
+
`--max-batch-bytes 52428800` and re-run; what already landed is not sent again.
|
|
60
|
+
|
|
61
|
+
## After the files land
|
|
62
|
+
|
|
63
|
+
Migration is not finished when the bytes arrive. Leave the AI something to work from:
|
|
64
|
+
|
|
65
|
+
1. Tell the user what landed and where (`--dest` path), and what was skipped or excluded.
|
|
66
|
+
2. Write down what the project is, how it runs, and what is missing — a project Wiki page
|
|
67
|
+
(`harvask wiki create -p PRJ`) is the right home; the AI reads it before working.
|
|
68
|
+
3. If the migration exists to get work done, file the first issue
|
|
69
|
+
(`harvask issue create -p PRJ`) describing that work.
|
|
70
|
+
|
|
71
|
+
Check the result in the Files tab (`/projects/{id}/files`) or with a fresh `--dry-run`:
|
|
72
|
+
everything should now report as `would_overwrite`, nothing as `would_create`.
|