@protoboxai/codeloop 0.3.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/LICENSE +21 -0
- package/README.md +589 -0
- package/dist/commands/adopt.d.ts +2 -0
- package/dist/commands/adopt.js +26 -0
- package/dist/commands/adopt.js.map +1 -0
- package/dist/commands/brief.d.ts +2 -0
- package/dist/commands/brief.js +22 -0
- package/dist/commands/brief.js.map +1 -0
- package/dist/commands/card.d.ts +6 -0
- package/dist/commands/card.js +159 -0
- package/dist/commands/card.js.map +1 -0
- package/dist/commands/check.d.ts +4 -0
- package/dist/commands/check.js +76 -0
- package/dist/commands/check.js.map +1 -0
- package/dist/commands/cloud.d.ts +8 -0
- package/dist/commands/cloud.js +123 -0
- package/dist/commands/cloud.js.map +1 -0
- package/dist/commands/guard.d.ts +2 -0
- package/dist/commands/guard.js +26 -0
- package/dist/commands/guard.js.map +1 -0
- package/dist/commands/import.d.ts +2 -0
- package/dist/commands/import.js +24 -0
- package/dist/commands/import.js.map +1 -0
- package/dist/commands/inbox.d.ts +2 -0
- package/dist/commands/inbox.js +48 -0
- package/dist/commands/inbox.js.map +1 -0
- package/dist/commands/init.d.ts +2 -0
- package/dist/commands/init.js +142 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/install.d.ts +2 -0
- package/dist/commands/install.js +125 -0
- package/dist/commands/install.js.map +1 -0
- package/dist/commands/lane.d.ts +2 -0
- package/dist/commands/lane.js +100 -0
- package/dist/commands/lane.js.map +1 -0
- package/dist/commands/list.d.ts +2 -0
- package/dist/commands/list.js +35 -0
- package/dist/commands/list.js.map +1 -0
- package/dist/commands/login.d.ts +2 -0
- package/dist/commands/login.js +77 -0
- package/dist/commands/login.js.map +1 -0
- package/dist/commands/mock.d.ts +3 -0
- package/dist/commands/mock.js +22 -0
- package/dist/commands/mock.js.map +1 -0
- package/dist/commands/pack.d.ts +2 -0
- package/dist/commands/pack.js +19 -0
- package/dist/commands/pack.js.map +1 -0
- package/dist/commands/publish.d.ts +2 -0
- package/dist/commands/publish.js +125 -0
- package/dist/commands/publish.js.map +1 -0
- package/dist/commands/remove.d.ts +2 -0
- package/dist/commands/remove.js +31 -0
- package/dist/commands/remove.js.map +1 -0
- package/dist/commands/render.d.ts +5 -0
- package/dist/commands/render.js +47 -0
- package/dist/commands/render.js.map +1 -0
- package/dist/commands/run.d.ts +2 -0
- package/dist/commands/run.js +45 -0
- package/dist/commands/run.js.map +1 -0
- package/dist/commands/scan.d.ts +2 -0
- package/dist/commands/scan.js +26 -0
- package/dist/commands/scan.js.map +1 -0
- package/dist/commands/schedule.d.ts +2 -0
- package/dist/commands/schedule.js +51 -0
- package/dist/commands/schedule.js.map +1 -0
- package/dist/commands/search.d.ts +2 -0
- package/dist/commands/search.js +85 -0
- package/dist/commands/search.js.map +1 -0
- package/dist/commands/serve.d.ts +7 -0
- package/dist/commands/serve.js +126 -0
- package/dist/commands/serve.js.map +1 -0
- package/dist/commands/spec.d.ts +3 -0
- package/dist/commands/spec.js +64 -0
- package/dist/commands/spec.js.map +1 -0
- package/dist/commands/status.d.ts +3 -0
- package/dist/commands/status.js +251 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/commands/update.d.ts +2 -0
- package/dist/commands/update.js +83 -0
- package/dist/commands/update.js.map +1 -0
- package/dist/commands/verify.d.ts +3 -0
- package/dist/commands/verify.js +75 -0
- package/dist/commands/verify.js.map +1 -0
- package/dist/commands/watch.d.ts +6 -0
- package/dist/commands/watch.js +111 -0
- package/dist/commands/watch.js.map +1 -0
- package/dist/commands/wiki.d.ts +3 -0
- package/dist/commands/wiki.js +85 -0
- package/dist/commands/wiki.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +86 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/agent.d.ts +27 -0
- package/dist/lib/agent.js +178 -0
- package/dist/lib/agent.js.map +1 -0
- package/dist/lib/board.d.ts +38 -0
- package/dist/lib/board.js +86 -0
- package/dist/lib/board.js.map +1 -0
- package/dist/lib/cards.d.ts +82 -0
- package/dist/lib/cards.js +107 -0
- package/dist/lib/cards.js.map +1 -0
- package/dist/lib/clock.d.ts +5 -0
- package/dist/lib/clock.js +14 -0
- package/dist/lib/clock.js.map +1 -0
- package/dist/lib/cloud.d.ts +122 -0
- package/dist/lib/cloud.js +580 -0
- package/dist/lib/cloud.js.map +1 -0
- package/dist/lib/competitors.d.ts +28 -0
- package/dist/lib/competitors.js +90 -0
- package/dist/lib/competitors.js.map +1 -0
- package/dist/lib/config.d.ts +7 -0
- package/dist/lib/config.js +25 -0
- package/dist/lib/config.js.map +1 -0
- package/dist/lib/cron.d.ts +5 -0
- package/dist/lib/cron.js +82 -0
- package/dist/lib/cron.js.map +1 -0
- package/dist/lib/detect.d.ts +13 -0
- package/dist/lib/detect.js +60 -0
- package/dist/lib/detect.js.map +1 -0
- package/dist/lib/engine.d.ts +88 -0
- package/dist/lib/engine.js +435 -0
- package/dist/lib/engine.js.map +1 -0
- package/dist/lib/flow.d.ts +44 -0
- package/dist/lib/flow.js +121 -0
- package/dist/lib/flow.js.map +1 -0
- package/dist/lib/glob.d.ts +2 -0
- package/dist/lib/glob.js +10 -0
- package/dist/lib/glob.js.map +1 -0
- package/dist/lib/import.d.ts +13 -0
- package/dist/lib/import.js +127 -0
- package/dist/lib/import.js.map +1 -0
- package/dist/lib/inbox.d.ts +42 -0
- package/dist/lib/inbox.js +65 -0
- package/dist/lib/inbox.js.map +1 -0
- package/dist/lib/lane.d.ts +71 -0
- package/dist/lib/lane.js +105 -0
- package/dist/lib/lane.js.map +1 -0
- package/dist/lib/lock.d.ts +6 -0
- package/dist/lib/lock.js +64 -0
- package/dist/lib/lock.js.map +1 -0
- package/dist/lib/mcp.d.ts +2 -0
- package/dist/lib/mcp.js +57 -0
- package/dist/lib/mcp.js.map +1 -0
- package/dist/lib/mock.d.ts +17 -0
- package/dist/lib/mock.js +137 -0
- package/dist/lib/mock.js.map +1 -0
- package/dist/lib/pack.d.ts +24 -0
- package/dist/lib/pack.js +77 -0
- package/dist/lib/pack.js.map +1 -0
- package/dist/lib/proposals.d.ts +48 -0
- package/dist/lib/proposals.js +240 -0
- package/dist/lib/proposals.js.map +1 -0
- package/dist/lib/render.d.ts +7 -0
- package/dist/lib/render.js +84 -0
- package/dist/lib/render.js.map +1 -0
- package/dist/lib/research.d.ts +8 -0
- package/dist/lib/research.js +39 -0
- package/dist/lib/research.js.map +1 -0
- package/dist/lib/run.d.ts +38 -0
- package/dist/lib/run.js +215 -0
- package/dist/lib/run.js.map +1 -0
- package/dist/lib/scaffold.d.ts +16 -0
- package/dist/lib/scaffold.js +175 -0
- package/dist/lib/scaffold.js.map +1 -0
- package/dist/lib/scan.d.ts +22 -0
- package/dist/lib/scan.js +85 -0
- package/dist/lib/scan.js.map +1 -0
- package/dist/lib/schedule.d.ts +20 -0
- package/dist/lib/schedule.js +66 -0
- package/dist/lib/schedule.js.map +1 -0
- package/dist/lib/server.d.ts +68 -0
- package/dist/lib/server.js +235 -0
- package/dist/lib/server.js.map +1 -0
- package/dist/lib/shell.d.ts +1 -0
- package/dist/lib/shell.js +25 -0
- package/dist/lib/shell.js.map +1 -0
- package/dist/lib/skills.d.ts +20 -0
- package/dist/lib/skills.js +92 -0
- package/dist/lib/skills.js.map +1 -0
- package/dist/lib/spec.d.ts +24 -0
- package/dist/lib/spec.js +102 -0
- package/dist/lib/spec.js.map +1 -0
- package/dist/lib/stats.d.ts +13 -0
- package/dist/lib/stats.js +43 -0
- package/dist/lib/stats.js.map +1 -0
- package/dist/lib/verify.d.ts +25 -0
- package/dist/lib/verify.js +135 -0
- package/dist/lib/verify.js.map +1 -0
- package/dist/lib/version.d.ts +10 -0
- package/dist/lib/version.js +27 -0
- package/dist/lib/version.js.map +1 -0
- package/dist/lib/wiki.d.ts +51 -0
- package/dist/lib/wiki.js +164 -0
- package/dist/lib/wiki.js.map +1 -0
- package/dist/registry/index.d.ts +7 -0
- package/dist/registry/index.js +8 -0
- package/dist/registry/index.js.map +1 -0
- package/dist/registry/installer.d.ts +30 -0
- package/dist/registry/installer.js +133 -0
- package/dist/registry/installer.js.map +1 -0
- package/dist/registry/local-index.d.ts +32 -0
- package/dist/registry/local-index.js +58 -0
- package/dist/registry/local-index.js.map +1 -0
- package/dist/registry/lockfile.d.ts +40 -0
- package/dist/registry/lockfile.js +85 -0
- package/dist/registry/lockfile.js.map +1 -0
- package/dist/registry/security.d.ts +25 -0
- package/dist/registry/security.js +100 -0
- package/dist/registry/security.js.map +1 -0
- package/dist/registry/skill-schema.d.ts +30 -0
- package/dist/registry/skill-schema.js +95 -0
- package/dist/registry/skill-schema.js.map +1 -0
- package/dist/ui/404.html +1 -0
- package/dist/ui/_next/static/6wzGE5sCtbYkSyhMWxL32/_buildManifest.js +1 -0
- package/dist/ui/_next/static/6wzGE5sCtbYkSyhMWxL32/_ssgManifest.js +1 -0
- package/dist/ui/_next/static/chunks/255-54d3085ce94738a4.js +1 -0
- package/dist/ui/_next/static/chunks/423-bb541b7ae2733575.js +1 -0
- package/dist/ui/_next/static/chunks/4bd1b696-c023c6e3521b1417.js +1 -0
- package/dist/ui/_next/static/chunks/app/_not-found/page-d6bc774f7acb716e.js +1 -0
- package/dist/ui/_next/static/chunks/app/layout-e5fc8e78e1c8da95.js +1 -0
- package/dist/ui/_next/static/chunks/app/page-0c34b6e119cef236.js +1 -0
- package/dist/ui/_next/static/chunks/framework-de98b93a850cfc71.js +1 -0
- package/dist/ui/_next/static/chunks/main-49fd204fc9037ea3.js +1 -0
- package/dist/ui/_next/static/chunks/main-app-c46afa2f48f3aaef.js +1 -0
- package/dist/ui/_next/static/chunks/pages/_app-7d307437aca18ad4.js +1 -0
- package/dist/ui/_next/static/chunks/pages/_error-cb2a52f75f2162e2.js +1 -0
- package/dist/ui/_next/static/chunks/polyfills-42372ed130431b0a.js +1 -0
- package/dist/ui/_next/static/chunks/webpack-4a462cecab786e93.js +1 -0
- package/dist/ui/_next/static/css/1bf01240dbfd6088.css +1 -0
- package/dist/ui/index.html +1 -0
- package/dist/ui/index.txt +19 -0
- package/dist/watch/index.d.ts +21 -0
- package/dist/watch/index.js +88 -0
- package/dist/watch/index.js.map +1 -0
- package/dist/watch/reporter.d.ts +11 -0
- package/dist/watch/reporter.js +44 -0
- package/dist/watch/reporter.js.map +1 -0
- package/dist/watch/signals.d.ts +38 -0
- package/dist/watch/signals.js +119 -0
- package/dist/watch/signals.js.map +1 -0
- package/dist/watch/triggers.d.ts +10 -0
- package/dist/watch/triggers.js +67 -0
- package/dist/watch/triggers.js.map +1 -0
- package/package.json +64 -0
- package/registry/index.json +106 -0
- package/starters/generic.yaml +95 -0
- package/starters/go.yaml +99 -0
- package/starters/node-typescript.yaml +108 -0
- package/starters/python.yaml +105 -0
- package/templates/ci/codeloop-pr.yml +29 -0
- package/templates/ci/codeloop-prod.yml +27 -0
- package/templates/ci/codeloop-staging.yml +34 -0
- package/templates/codeloop/board.json +5 -0
- package/templates/codeloop/gotchas.md +13 -0
- package/templates/codeloop/patterns.md +15 -0
- package/templates/codeloop/principles.md +49 -0
- package/templates/codeloop/rules.md +23 -0
- package/templates/commands/commit.md +255 -0
- package/templates/commands/debug.md +142 -0
- package/templates/commands/deploy.md +144 -0
- package/templates/commands/design.md +102 -0
- package/templates/commands/manage.md +77 -0
- package/templates/commands/plan.md +84 -0
- package/templates/commands/qa.md +155 -0
- package/templates/commands/reflect.md +93 -0
- package/templates/commands/ship.md +187 -0
- package/templates/commands/test.md +133 -0
- package/templates/hooks/commit-msg +8 -0
- package/templates/lanes/analyze.yaml +25 -0
- package/templates/lanes/build.yaml +45 -0
- package/templates/lanes/deploy.yaml +24 -0
- package/templates/lanes/learn.yaml +20 -0
- package/templates/lanes/market.yaml +25 -0
- package/templates/lanes/plan.yaml +24 -0
- package/templates/lanes/scan.yaml +11 -0
- package/templates/lanes/triage.yaml +24 -0
- package/templates/mock/template.html +82 -0
- package/templates/seeds/go-gotchas.md +28 -0
- package/templates/seeds/go-patterns.md +22 -0
- package/templates/seeds/node-typescript-gotchas.md +30 -0
- package/templates/seeds/node-typescript-patterns.md +27 -0
- package/templates/seeds/python-gotchas.md +30 -0
- package/templates/seeds/python-patterns.md +19 -0
- package/templates/seeds/universal-gotchas.md +11 -0
- package/templates/seeds/universal-patterns.md +11 -0
- package/templates/spec/plan.md +7 -0
- package/templates/spec/research.md +19 -0
- package/templates/spec/spec.md +14 -0
- package/templates/spec/tasks.md +10 -0
- package/templates/tasks/todo.md +3 -0
|
@@ -0,0 +1,580 @@
|
|
|
1
|
+
import { spawnSync } from 'child_process';
|
|
2
|
+
import { createHash } from 'crypto';
|
|
3
|
+
import { existsSync, mkdirSync, readdirSync, readFileSync, renameSync, rmSync, writeFileSync } from 'fs';
|
|
4
|
+
import { dirname, join } from 'path';
|
|
5
|
+
import { withLock } from './lock.js';
|
|
6
|
+
// This module must not import cards.ts: cards.ts calls it on every write.
|
|
7
|
+
export const CLOUD_FILE = '.codeloop/cloud.json';
|
|
8
|
+
export const SYNC_FILE = '.codeloop/state/sync.json';
|
|
9
|
+
const STATE_DIR = '.codeloop';
|
|
10
|
+
const BOARD = 'cards.json';
|
|
11
|
+
const CONFIG = 'config.yaml';
|
|
12
|
+
const DEFAULT_FOLDER = 'codeloop';
|
|
13
|
+
const WIKI_FOLDERS = ['gotchas', 'decisions', 'concepts', 'competitors'];
|
|
14
|
+
const WIKI_TITLE = new RegExp(`\\((${WIKI_FOLDERS.join('|')})/([^)/]+\\.md)\\)$`);
|
|
15
|
+
const LANE_FILE = /^[A-Za-z0-9][A-Za-z0-9._-]*\.yaml$/;
|
|
16
|
+
/** A wiki page changed on both sides: the cloud version is written beside the local one under this suffix. */
|
|
17
|
+
export const CLOUD_COPY = '.cloud.md';
|
|
18
|
+
const EMPTY_BOARD = JSON.stringify({ version: 0, cards: [] }, null, 2) + '\n';
|
|
19
|
+
const SYNC_TIMEOUT_MS = 10_000;
|
|
20
|
+
export class CloudError extends Error {
|
|
21
|
+
}
|
|
22
|
+
/** The page moved on since this project last saw it: someone else wrote first. */
|
|
23
|
+
export class CloudConflictError extends CloudError {
|
|
24
|
+
}
|
|
25
|
+
const unreachable = (e) => e instanceof CloudError && !(e instanceof CloudConflictError) && e.message.startsWith('cloud store unreachable');
|
|
26
|
+
const sha = (text) => createHash('sha256').update(text).digest('hex');
|
|
27
|
+
export function loadCloud(projectDir) {
|
|
28
|
+
const file = join(projectDir, CLOUD_FILE);
|
|
29
|
+
return existsSync(file) ? JSON.parse(readFileSync(file, 'utf-8')) : null;
|
|
30
|
+
}
|
|
31
|
+
function saveCloud(projectDir, config) {
|
|
32
|
+
const file = join(projectDir, CLOUD_FILE);
|
|
33
|
+
mkdirSync(dirname(file), { recursive: true });
|
|
34
|
+
writeFileSync(file, JSON.stringify(config, null, 2) + '\n', { mode: 0o600 });
|
|
35
|
+
}
|
|
36
|
+
export function loadSync(projectDir) {
|
|
37
|
+
const file = join(projectDir, SYNC_FILE);
|
|
38
|
+
if (existsSync(file))
|
|
39
|
+
return JSON.parse(readFileSync(file, 'utf-8'));
|
|
40
|
+
// A connection made before sync.json existed kept its page refs in cloud.json.
|
|
41
|
+
const old = loadCloud(projectDir);
|
|
42
|
+
const documents = {};
|
|
43
|
+
if (old?.board)
|
|
44
|
+
documents[BOARD] = { kind: 'board', ...old.board, hash: null };
|
|
45
|
+
for (const [path, ref] of Object.entries(old?.wiki ?? {}))
|
|
46
|
+
documents[`wiki/${path}`] = { kind: 'wiki', ...ref, hash: null };
|
|
47
|
+
return { documents };
|
|
48
|
+
}
|
|
49
|
+
function saveSync(projectDir, sync) {
|
|
50
|
+
const file = join(projectDir, SYNC_FILE);
|
|
51
|
+
mkdirSync(dirname(file), { recursive: true });
|
|
52
|
+
writeFileSync(`${file}.${process.pid}.tmp`, JSON.stringify(sync, null, 2) + '\n');
|
|
53
|
+
renameSync(`${file}.${process.pid}.tmp`, file);
|
|
54
|
+
}
|
|
55
|
+
// Card writes are synchronous everywhere, and Node has no synchronous HTTP. Each call runs this
|
|
56
|
+
// script in a child process; the key goes in on stdin so it never appears in a process listing.
|
|
57
|
+
const BRIDGE = `
|
|
58
|
+
const chunks = []; for await (const c of process.stdin) chunks.push(c);
|
|
59
|
+
const { url, key, calls, timeoutMs } = JSON.parse(Buffer.concat(chunks).toString());
|
|
60
|
+
const post = async (body, attempt = 0) => {
|
|
61
|
+
const res = await fetch(url, { method: 'POST', signal: AbortSignal.timeout(timeoutMs), headers: { 'content-type': 'application/json', accept: 'application/json, text/event-stream', authorization: 'Bearer ' + key }, body: JSON.stringify(body) });
|
|
62
|
+
const text = await res.text();
|
|
63
|
+
// The endpoint rate-limits; it says how long to wait.
|
|
64
|
+
if (res.status === 429 && attempt < 6) {
|
|
65
|
+
await new Promise(r => setTimeout(r, (Number(res.headers.get('retry-after')) || 2) * 1000));
|
|
66
|
+
return post(body, attempt + 1);
|
|
67
|
+
}
|
|
68
|
+
if (!res.ok) throw new Error('HTTP ' + res.status + ' ' + text.slice(0, 200));
|
|
69
|
+
const line = text.split('\\n').find(l => l.startsWith('data:'));
|
|
70
|
+
return JSON.parse(line ? line.slice(5) : text);
|
|
71
|
+
};
|
|
72
|
+
process.on('uncaughtException', e => { console.error(e.cause?.code ?? e.message); process.exit(1); });
|
|
73
|
+
// The endpoint answers a tool call with no handshake and allows 60 requests a minute, so the
|
|
74
|
+
// handshake is sent only to a server that asks for it.
|
|
75
|
+
const handshake = () => post({ jsonrpc: '2.0', id: 0, method: 'initialize', params: { protocolVersion: '2024-11-05', capabilities: {}, clientInfo: { name: 'codeloop', version: '0' } } });
|
|
76
|
+
const wantsHandshake = text => /not initialized|initialize first|session/i.test(text);
|
|
77
|
+
const out = []; let id = 1; let greeted = false;
|
|
78
|
+
for (const c of calls) {
|
|
79
|
+
const body = { jsonrpc: '2.0', id: id++, method: 'tools/call', params: { name: c.name, arguments: c.args } };
|
|
80
|
+
let reply;
|
|
81
|
+
try {
|
|
82
|
+
reply = await post(body);
|
|
83
|
+
} catch (e) {
|
|
84
|
+
if (greeted || !wantsHandshake(e.message)) throw e;
|
|
85
|
+
}
|
|
86
|
+
if (!greeted && (!reply || (reply.error && wantsHandshake(reply.error.message ?? '')))) {
|
|
87
|
+
await handshake();
|
|
88
|
+
greeted = true;
|
|
89
|
+
reply = await post(body);
|
|
90
|
+
}
|
|
91
|
+
out.push(reply);
|
|
92
|
+
}
|
|
93
|
+
process.stdout.write(JSON.stringify(out));
|
|
94
|
+
`;
|
|
95
|
+
/** Runs tool calls in order and returns each one's `data`. Throws CloudConflictError on VERSION_CONFLICT. */
|
|
96
|
+
export function callTools(conn, calls, timeoutMs = 60_000) {
|
|
97
|
+
const run = spawnSync(process.execPath, ['--input-type=module', '-e', BRIDGE], {
|
|
98
|
+
input: JSON.stringify({ url: conn.url, key: conn.key, calls, timeoutMs }),
|
|
99
|
+
encoding: 'utf-8',
|
|
100
|
+
timeout: 120_000,
|
|
101
|
+
});
|
|
102
|
+
if (run.status !== 0)
|
|
103
|
+
throw new CloudError(`cloud store unreachable at ${conn.url}: ${(run.stderr ?? '').trim().split('\n').at(-1) ?? 'no response'}`);
|
|
104
|
+
return JSON.parse(run.stdout).map((rpc, i) => {
|
|
105
|
+
const text = rpc.result?.content?.[0]?.text ?? rpc.error?.message ?? '';
|
|
106
|
+
let body;
|
|
107
|
+
try {
|
|
108
|
+
body = JSON.parse(text);
|
|
109
|
+
}
|
|
110
|
+
catch {
|
|
111
|
+
throw new CloudError(`${calls[i].name}: ${text || 'empty response'}`);
|
|
112
|
+
}
|
|
113
|
+
const result = body.result ?? body;
|
|
114
|
+
if (result.success === false || rpc.result?.isError || body.status === 'action_not_allowed') {
|
|
115
|
+
const message = `${calls[i].name}: ${result.error ?? body.message ?? text}`;
|
|
116
|
+
throw String(message).includes('VERSION_CONFLICT') ? new CloudConflictError(message) : new CloudError(message);
|
|
117
|
+
}
|
|
118
|
+
return result.data ?? result;
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
function listPages(config, timeoutMs) {
|
|
122
|
+
const [data] = callTools(config, [{ name: 'KNOWLEDGE_LIST_PAGES', args: {} }], timeoutMs);
|
|
123
|
+
const pages = (data.pages ?? []).map(p => ({ id: p.id, title: p.title, revision: p.latestRevisionN, folderId: p.folderId }));
|
|
124
|
+
return { pages, folders: data.folders ?? [] };
|
|
125
|
+
}
|
|
126
|
+
function readPages(config, ids) {
|
|
127
|
+
const data = ids.length ? callTools(config, ids.map(pageId => ({ name: 'KNOWLEDGE_READ_PAGE', args: { pageId } }))) : [];
|
|
128
|
+
return new Map(ids.map((id, i) => [id, { content: data[i].content ?? '', revision: data[i].latestRevisionN }]));
|
|
129
|
+
}
|
|
130
|
+
const rootFolder = (config) => config.folder ?? DEFAULT_FOLDER;
|
|
131
|
+
// The workspace files a page under an existing folder of the same name wherever that folder sits,
|
|
132
|
+
// so a plain `wiki` or `lanes` would be shared with every other project. The root name is repeated
|
|
133
|
+
// in the subfolder name to keep each project's pages together.
|
|
134
|
+
const subFolder = (config, name) => `${rootFolder(config)}/${rootFolder(config).replace(/^.*\//, '')}-${name}`;
|
|
135
|
+
function folderId(folders, name) {
|
|
136
|
+
for (const folder of folders) {
|
|
137
|
+
const id = folder.name === name ? folder.id : folderId(folder.children ?? [], name);
|
|
138
|
+
if (id)
|
|
139
|
+
return id;
|
|
140
|
+
}
|
|
141
|
+
return undefined;
|
|
142
|
+
}
|
|
143
|
+
// The path rides in the title so a pull into another checkout can put the file back where it was.
|
|
144
|
+
function wikiTitle(rel, content) {
|
|
145
|
+
const title = /^title:\s*(.+)$/m.exec(content)?.[1].replace(/^["']|["']$/g, '') ?? rel.replace(/^.*\//, '').replace(/\.md$/, '');
|
|
146
|
+
return `${title} (${rel})`;
|
|
147
|
+
}
|
|
148
|
+
function kindOf(path) {
|
|
149
|
+
return path === BOARD ? 'board' : path === CONFIG ? 'config' : path.startsWith('lanes/') ? 'lane' : 'wiki';
|
|
150
|
+
}
|
|
151
|
+
function page(config, path, content) {
|
|
152
|
+
const root = rootFolder(config);
|
|
153
|
+
switch (kindOf(path)) {
|
|
154
|
+
case 'board': return { title: config.boardTitle, folder: root };
|
|
155
|
+
case 'config': return { title: `${config.boardTitle}: ${CONFIG}`, folder: root };
|
|
156
|
+
case 'lane': return { title: `${config.boardTitle}: ${path}`, folder: subFolder(config, 'lanes') };
|
|
157
|
+
case 'wiki': return { title: wikiTitle(path.replace(/^wiki\//, ''), content), folder: subFolder(config, 'wiki') };
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
/** The local path a page belongs to, or undefined for a page that is not one of this project's documents. */
|
|
161
|
+
function pathOf(config, remote, wikiFolder) {
|
|
162
|
+
if (remote.title === config.boardTitle)
|
|
163
|
+
return BOARD;
|
|
164
|
+
const prefix = `${config.boardTitle}: `;
|
|
165
|
+
if (remote.title.startsWith(prefix)) {
|
|
166
|
+
const rest = remote.title.slice(prefix.length);
|
|
167
|
+
if (rest === CONFIG)
|
|
168
|
+
return CONFIG;
|
|
169
|
+
if (rest.startsWith('lanes/') && LANE_FILE.test(rest.slice(6)))
|
|
170
|
+
return rest;
|
|
171
|
+
return undefined;
|
|
172
|
+
}
|
|
173
|
+
// Titles are shared across the workspace, so a wiki page counts only when it sits in this project's wiki folder.
|
|
174
|
+
const m = WIKI_TITLE.exec(remote.title);
|
|
175
|
+
return m && wikiFolder && remote.folderId === wikiFolder ? `wiki/${m[1]}/${m[2]}` : undefined;
|
|
176
|
+
}
|
|
177
|
+
const abs = (projectDir, path) => join(projectDir, STATE_DIR, path);
|
|
178
|
+
function localPaths(projectDir) {
|
|
179
|
+
const paths = [BOARD];
|
|
180
|
+
if (existsSync(abs(projectDir, CONFIG)))
|
|
181
|
+
paths.push(CONFIG);
|
|
182
|
+
const lanes = abs(projectDir, 'lanes');
|
|
183
|
+
if (existsSync(lanes))
|
|
184
|
+
paths.push(...readdirSync(lanes).filter(f => LANE_FILE.test(f)).sort().map(f => `lanes/${f}`));
|
|
185
|
+
for (const folder of WIKI_FOLDERS) {
|
|
186
|
+
const dir = abs(projectDir, `wiki/${folder}`);
|
|
187
|
+
if (existsSync(dir))
|
|
188
|
+
paths.push(...readdirSync(dir).filter(f => f.endsWith('.md') && !f.endsWith(CLOUD_COPY)).sort().map(f => `wiki/${folder}/${f}`));
|
|
189
|
+
}
|
|
190
|
+
return paths;
|
|
191
|
+
}
|
|
192
|
+
function readLocal(projectDir, path) {
|
|
193
|
+
const file = abs(projectDir, path);
|
|
194
|
+
return existsSync(file) ? readFileSync(file, 'utf-8') : null;
|
|
195
|
+
}
|
|
196
|
+
const copyPath = (projectDir, path) => abs(projectDir, path.replace(/\.md$/, CLOUD_COPY));
|
|
197
|
+
// Compared as data: the store trims trailing whitespace from what it hands back.
|
|
198
|
+
function same(kind, a, b) {
|
|
199
|
+
if (kind !== 'board')
|
|
200
|
+
return a.trimEnd() === b.trimEnd();
|
|
201
|
+
try {
|
|
202
|
+
return JSON.stringify(JSON.parse(a)) === JSON.stringify(JSON.parse(b));
|
|
203
|
+
}
|
|
204
|
+
catch {
|
|
205
|
+
return false;
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
function stateOf(projectDir, row) {
|
|
209
|
+
const { entry, remote, kind } = row;
|
|
210
|
+
if (!remote)
|
|
211
|
+
return 'local-ahead';
|
|
212
|
+
if (!entry)
|
|
213
|
+
return row.local === null ? 'cloud-ahead' : 'both-changed';
|
|
214
|
+
if (entry.diverged || (kind === 'wiki' && existsSync(copyPath(projectDir, row.path))))
|
|
215
|
+
return 'both-changed';
|
|
216
|
+
// A file that is not here has nothing local to lose. A board that was never written is the
|
|
217
|
+
// empty board, so it is compared like any other once it has matched the page.
|
|
218
|
+
if (row.local === null && (entry.hash === null || kind !== 'board'))
|
|
219
|
+
return 'cloud-ahead';
|
|
220
|
+
const localChanged = !!entry.pending || sha(row.local ?? EMPTY_BOARD) !== entry.hash;
|
|
221
|
+
const cloudChanged = remote.revision !== entry.revision;
|
|
222
|
+
return localChanged ? (cloudChanged ? 'both-changed' : 'local-ahead') : cloudChanged ? 'cloud-ahead' : 'in-sync';
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* One listing of the workspace against the local files and the sync record. A local file that
|
|
226
|
+
* meets a page it has no record of is read once: identical content is recorded as in sync.
|
|
227
|
+
*/
|
|
228
|
+
function open(projectDir, config, sync, timeoutMs) {
|
|
229
|
+
const { pages, folders } = listPages(config, timeoutMs);
|
|
230
|
+
const wikiFolder = folderId(folders, subFolder(config, 'wiki').replace(/^.*\//, ''));
|
|
231
|
+
const byId = new Map(pages.map(p => [p.id, p]));
|
|
232
|
+
const discovered = new Map();
|
|
233
|
+
for (const p of pages) {
|
|
234
|
+
const path = pathOf(config, p, wikiFolder);
|
|
235
|
+
if (path)
|
|
236
|
+
discovered.set(path, p);
|
|
237
|
+
}
|
|
238
|
+
const paths = [...new Set([...localPaths(projectDir), ...Object.keys(sync.documents), ...discovered.keys()])];
|
|
239
|
+
const rows = paths.map(path => {
|
|
240
|
+
const local = readLocal(projectDir, path);
|
|
241
|
+
const entry = sync.documents[path];
|
|
242
|
+
const kind = kindOf(path);
|
|
243
|
+
// A write with no page id lands on whatever page has the title, so that page is the remote.
|
|
244
|
+
const byTitle = local !== null && kind === 'wiki' ? pages.find(p => p.title === wikiTitle(path.slice(5), local)) : undefined;
|
|
245
|
+
const remote = (entry?.pageId ? byId.get(entry.pageId) : undefined) ?? discovered.get(path) ?? byTitle;
|
|
246
|
+
return { path, kind, local, entry, remote, state: 'in-sync' };
|
|
247
|
+
});
|
|
248
|
+
const strangers = rows.filter(r => !r.entry && r.remote && (r.local !== null || r.kind === 'board'));
|
|
249
|
+
const contents = readPages(config, strangers.map(r => r.remote.id));
|
|
250
|
+
for (const row of strangers) {
|
|
251
|
+
const remote = contents.get(row.remote.id);
|
|
252
|
+
if (row.local !== null && same(row.kind, row.local, remote.content)) {
|
|
253
|
+
row.entry = sync.documents[row.path] = { kind: row.kind, pageId: row.remote.id, revision: remote.revision, hash: sha(row.local) };
|
|
254
|
+
}
|
|
255
|
+
else if (row.kind === 'board') {
|
|
256
|
+
// An existing board is adopted as it is. With no local board there is nothing to lose and the
|
|
257
|
+
// next pull takes it; with a different one, neither side is taken until the owner says which.
|
|
258
|
+
row.entry = sync.documents[row.path] = { kind: 'board', pageId: row.remote.id, revision: remote.revision, hash: null, ...(row.local !== null ? { diverged: true } : {}) };
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
for (const row of rows)
|
|
262
|
+
row.state = stateOf(projectDir, row);
|
|
263
|
+
return { projectDir, config, sync, rows, notes: [] };
|
|
264
|
+
}
|
|
265
|
+
function writePage(config, title, folder, content, entry) {
|
|
266
|
+
const [data] = callTools(config, [{
|
|
267
|
+
name: 'KNOWLEDGE_WRITE_PAGE',
|
|
268
|
+
args: { title, folder, content, mode: 'replace', ...(entry?.pageId ? { pageId: entry.pageId, expectedVersion: entry.revision } : {}) },
|
|
269
|
+
}]);
|
|
270
|
+
// The store leaves the revision out of some replies (seen when it creates a longer page), and a
|
|
271
|
+
// record without one would read as changed in the cloud ever after. The page itself always has it.
|
|
272
|
+
return { pageId: data.pageId, revision: data.revision ?? readPages(config, [data.pageId]).get(data.pageId).revision };
|
|
273
|
+
}
|
|
274
|
+
/** Writes the local content to its page, expecting the revision last seen, and records the result. */
|
|
275
|
+
function upload(s, row, content, expect) {
|
|
276
|
+
const { title, folder } = page(s.config, row.path, content);
|
|
277
|
+
const ref = writePage(s.config, title, folder, content, expect);
|
|
278
|
+
row.entry = s.sync.documents[row.path] = { kind: row.kind, ...ref, hash: sha(content) };
|
|
279
|
+
row.remote = { id: ref.pageId, title, revision: ref.revision };
|
|
280
|
+
row.state = 'in-sync';
|
|
281
|
+
}
|
|
282
|
+
function writeLocal(projectDir, path, content) {
|
|
283
|
+
const text = `${content.trimEnd()}\n`;
|
|
284
|
+
if (kindOf(path) === 'board')
|
|
285
|
+
JSON.parse(text); // a board page that is not JSON must not replace cards.json
|
|
286
|
+
const file = abs(projectDir, path);
|
|
287
|
+
mkdirSync(dirname(file), { recursive: true });
|
|
288
|
+
writeFileSync(`${file}.pull.tmp`, text);
|
|
289
|
+
renameSync(`${file}.pull.tmp`, file);
|
|
290
|
+
return text;
|
|
291
|
+
}
|
|
292
|
+
/**
|
|
293
|
+
* Writes that were kept locally while the cloud was unreachable go first, with the revision they
|
|
294
|
+
* were made against. A board whose page moved meanwhile is refused; anything else is left for the
|
|
295
|
+
* pull step, which treats it as changed on both sides.
|
|
296
|
+
*/
|
|
297
|
+
function pushPending(s) {
|
|
298
|
+
for (const row of s.rows.filter(r => r.entry?.pending && r.local !== null)) {
|
|
299
|
+
const entry = row.entry;
|
|
300
|
+
if (row.remote && row.remote.revision !== entry.revision) {
|
|
301
|
+
if (row.kind !== 'board')
|
|
302
|
+
continue;
|
|
303
|
+
throw new CloudConflictError(`VERSION_CONFLICT: the cloud board is at revision ${row.remote.revision}; this checkout last saw revision ${entry.revision} and holds a write that was never pushed`);
|
|
304
|
+
}
|
|
305
|
+
upload(s, row, row.local, entry);
|
|
306
|
+
s.notes.push(`pushed pending ${row.path} (revision ${row.entry.revision})`);
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
/**
|
|
310
|
+
* `unchanged` updates only files nobody edited here. `board` also takes a board that changed on
|
|
311
|
+
* both sides, which is how a refused card write is retried. `force` takes every cloud copy.
|
|
312
|
+
*/
|
|
313
|
+
function pullRows(s, mode) {
|
|
314
|
+
const takes = (r) => r.state === 'cloud-ahead' || (r.state === 'both-changed' && (mode === 'force' || (mode === 'board' && r.kind === 'board')));
|
|
315
|
+
const wanted = s.rows.filter(r => r.remote && (takes(r) || (r.state === 'both-changed' && r.kind === 'wiki')));
|
|
316
|
+
const contents = readPages(s.config, wanted.map(r => r.remote.id));
|
|
317
|
+
for (const row of wanted) {
|
|
318
|
+
const remote = contents.get(row.remote.id);
|
|
319
|
+
if (takes(row)) {
|
|
320
|
+
const text = writeLocal(s.projectDir, row.path, remote.content);
|
|
321
|
+
if (row.kind === 'wiki')
|
|
322
|
+
rmSync(copyPath(s.projectDir, row.path), { force: true });
|
|
323
|
+
row.entry = s.sync.documents[row.path] = { kind: row.kind, pageId: row.remote.id, revision: remote.revision, hash: sha(text) };
|
|
324
|
+
row.local = text;
|
|
325
|
+
row.state = 'in-sync';
|
|
326
|
+
s.notes.push(`pulled ${row.path} (revision ${remote.revision})`);
|
|
327
|
+
}
|
|
328
|
+
else if (same('wiki', row.local ?? '', remote.content)) {
|
|
329
|
+
// Both sides made the same edit.
|
|
330
|
+
rmSync(copyPath(s.projectDir, row.path), { force: true });
|
|
331
|
+
row.entry = s.sync.documents[row.path] = { kind: 'wiki', pageId: row.remote.id, revision: remote.revision, hash: sha(row.local) };
|
|
332
|
+
row.state = 'in-sync';
|
|
333
|
+
}
|
|
334
|
+
else {
|
|
335
|
+
const copy = copyPath(s.projectDir, row.path);
|
|
336
|
+
const text = `${remote.content.trimEnd()}\n`;
|
|
337
|
+
if (!existsSync(copy) || readFileSync(copy, 'utf-8') !== text) {
|
|
338
|
+
writeFileSync(copy, text);
|
|
339
|
+
s.notes.push(`${row.path} changed here and in the cloud; the cloud version is beside it as ${copy.replace(/^.*\//, '')}. Merge it into yours, then delete it.`);
|
|
340
|
+
}
|
|
341
|
+
// The merge is pushed against the revision just seen, once the copy is gone.
|
|
342
|
+
row.entry = s.sync.documents[row.path] = { kind: 'wiki', pageId: row.remote.id, revision: remote.revision, hash: row.entry?.hash ?? null };
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
for (const row of s.rows.filter(r => r.state === 'both-changed' && r.kind !== 'wiki' && r.remote)) {
|
|
346
|
+
if (!row.entry)
|
|
347
|
+
row.entry = s.sync.documents[row.path] = { kind: row.kind, pageId: row.remote.id, revision: row.remote.revision, hash: null, diverged: true };
|
|
348
|
+
if (row.kind !== 'board')
|
|
349
|
+
s.notes.push(`${row.path} changed here and in the cloud; yours was kept. \`codeloop cloud pull --force\` takes the cloud copy, \`codeloop cloud push --force\` replaces it.`);
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
/**
|
|
353
|
+
* `edits` is what a command does by itself: wiki pages and config edited here. A lane edited here
|
|
354
|
+
* is never pushed; it reaches the cloud through `lane promote`. `initial` is the first upload on
|
|
355
|
+
* connect, `all` adds the board, `force` also replaces pages that changed in the cloud.
|
|
356
|
+
*/
|
|
357
|
+
function pushRows(s, mode) {
|
|
358
|
+
const pushed = [];
|
|
359
|
+
const held = [];
|
|
360
|
+
for (const row of s.rows) {
|
|
361
|
+
if (row.local === null && row.kind !== 'board')
|
|
362
|
+
continue;
|
|
363
|
+
const forced = mode === 'force' && row.state === 'both-changed' && row.kind !== 'lane';
|
|
364
|
+
if (row.state !== 'local-ahead' && !forced)
|
|
365
|
+
continue;
|
|
366
|
+
if (row.kind === 'lane' && !(mode === 'initial' && !row.remote)) {
|
|
367
|
+
held.push(row.path);
|
|
368
|
+
s.notes.push(`${row.path} was edited here and is not pushed; a lane changes through \`codeloop lane propose\`, \`lane eval\` and \`lane promote\`.`);
|
|
369
|
+
continue;
|
|
370
|
+
}
|
|
371
|
+
if (row.kind === 'board' && mode === 'edits')
|
|
372
|
+
continue;
|
|
373
|
+
const expect = forced && row.entry ? { ...row.entry, revision: row.remote.revision } : row.entry;
|
|
374
|
+
upload(s, row, row.local ?? EMPTY_BOARD, expect);
|
|
375
|
+
if (row.kind === 'wiki')
|
|
376
|
+
rmSync(copyPath(s.projectDir, row.path), { force: true });
|
|
377
|
+
pushed.push(row);
|
|
378
|
+
if (mode === 'edits')
|
|
379
|
+
s.notes.push(`pushed ${row.path} (revision ${row.entry.revision})`);
|
|
380
|
+
}
|
|
381
|
+
return { pushed, held };
|
|
382
|
+
}
|
|
383
|
+
function ignoreLocalFiles(projectDir) {
|
|
384
|
+
const file = join(projectDir, '.codeloop/.gitignore');
|
|
385
|
+
const current = existsSync(file) ? readFileSync(file, 'utf-8') : '';
|
|
386
|
+
const missing = ['cloud.json', 'local.yaml', 'state/sync.json'].filter(l => !current.split('\n').includes(l));
|
|
387
|
+
if (missing.length)
|
|
388
|
+
writeFileSync(file, `${current.trimEnd()}${current.trim() ? '\n' : ''}${missing.join('\n')}\n`);
|
|
389
|
+
}
|
|
390
|
+
/**
|
|
391
|
+
* A board page that already exists under the same title is adopted as it is, never overwritten:
|
|
392
|
+
* another checkout may have written it. `cloud pull` takes it, `cloud push --force` replaces it.
|
|
393
|
+
* Config, lanes and wiki pages that are not in the workspace yet are uploaded.
|
|
394
|
+
*/
|
|
395
|
+
export function connect(projectDir, input) {
|
|
396
|
+
const config = {
|
|
397
|
+
url: input.url,
|
|
398
|
+
key: input.key,
|
|
399
|
+
workspaceName: input.workspaceName,
|
|
400
|
+
boardTitle: input.boardTitle ?? process.env.CODELOOP_CLOUD_BOARD_TITLE ?? 'codeloop board',
|
|
401
|
+
folder: input.folder ?? process.env.CODELOOP_CLOUD_FOLDER ?? DEFAULT_FOLDER,
|
|
402
|
+
};
|
|
403
|
+
const s = open(projectDir, config, { documents: {} });
|
|
404
|
+
const board = s.rows.find(r => r.kind === 'board');
|
|
405
|
+
const adopted = !!board.remote;
|
|
406
|
+
// The board is left where it is; everything else that only the cloud has is taken.
|
|
407
|
+
if (adopted)
|
|
408
|
+
board.state = 'in-sync';
|
|
409
|
+
pullRows(s, 'unchanged');
|
|
410
|
+
const { pushed } = pushRows(s, 'initial');
|
|
411
|
+
saveCloud(projectDir, config);
|
|
412
|
+
saveSync(projectDir, s.sync);
|
|
413
|
+
ignoreLocalFiles(projectDir);
|
|
414
|
+
return { adopted, revision: s.sync.documents[BOARD].revision, wikiPages: pushed.filter(r => r.kind === 'wiki').length, notes: s.notes.filter(n => !n.startsWith('pulled ')) };
|
|
415
|
+
}
|
|
416
|
+
// sync.json records the revision last seen for each page. Board writes, wiki writes, push and
|
|
417
|
+
// pull all read it, call the store and write it back, so they take turns. Anything that may
|
|
418
|
+
// replace cards.json takes that lock first, the same order a card write uses.
|
|
419
|
+
function locked(projectDir, fn) {
|
|
420
|
+
return withLock(join(projectDir, CLOUD_FILE), fn);
|
|
421
|
+
}
|
|
422
|
+
const withBoard = (projectDir, fn) => withLock(join(projectDir, STATE_DIR, BOARD), () => locked(projectDir, fn));
|
|
423
|
+
/** One document written by a command: the page first, expecting the revision last seen. Unreachable means kept locally and marked pending. */
|
|
424
|
+
function writeDoc(projectDir, path, content, what) {
|
|
425
|
+
const config = loadCloud(projectDir);
|
|
426
|
+
if (!config)
|
|
427
|
+
return;
|
|
428
|
+
const sync = loadSync(projectDir);
|
|
429
|
+
const entry = sync.documents[path];
|
|
430
|
+
const kind = kindOf(path);
|
|
431
|
+
if (kind === 'board' && !entry)
|
|
432
|
+
return;
|
|
433
|
+
if (entry?.diverged)
|
|
434
|
+
throw new CloudConflictError(`VERSION_CONFLICT: ${path} differs from the cloud copy and neither has been taken`);
|
|
435
|
+
try {
|
|
436
|
+
const { title, folder } = page(config, path, content);
|
|
437
|
+
sync.documents[path] = { kind, ...writePage(config, title, folder, content, entry), hash: sha(content) };
|
|
438
|
+
}
|
|
439
|
+
catch (e) {
|
|
440
|
+
// A wiki page that also changed in the cloud is not refused: the next command writes the cloud version beside it.
|
|
441
|
+
if (!unreachable(e) && !(kind === 'wiki' && e instanceof CloudConflictError))
|
|
442
|
+
throw e;
|
|
443
|
+
console.error(unreachable(e)
|
|
444
|
+
? `warning: ${e.message}; ${what} was saved locally only and will be pushed by the next command that reaches the cloud.`
|
|
445
|
+
: `warning: ${what} also changed in the cloud; the next command writes the cloud version beside yours.`);
|
|
446
|
+
sync.documents[path] = { kind, pageId: entry?.pageId ?? '', revision: entry?.revision ?? 0, hash: entry?.hash ?? null, pending: true };
|
|
447
|
+
}
|
|
448
|
+
saveSync(projectDir, sync);
|
|
449
|
+
}
|
|
450
|
+
/**
|
|
451
|
+
* Called by every card write before the local file changes. A stale revision throws
|
|
452
|
+
* CloudConflictError and the caller leaves the local file alone. If the cloud cannot be reached
|
|
453
|
+
* the write stays local and is marked pending in sync.json.
|
|
454
|
+
*/
|
|
455
|
+
export function writeCloudBoard(projectDir, content) {
|
|
456
|
+
if (!existsSync(join(projectDir, CLOUD_FILE)))
|
|
457
|
+
return;
|
|
458
|
+
return locked(projectDir, () => writeDoc(projectDir, BOARD, content, 'the board'));
|
|
459
|
+
}
|
|
460
|
+
export function writeCloudWikiPage(projectDir, path) {
|
|
461
|
+
if (!existsSync(join(projectDir, CLOUD_FILE)))
|
|
462
|
+
return;
|
|
463
|
+
const rel = path.replace(`${STATE_DIR}/`, '');
|
|
464
|
+
const content = readLocal(projectDir, rel);
|
|
465
|
+
if (content === null)
|
|
466
|
+
return;
|
|
467
|
+
return locked(projectDir, () => writeDoc(projectDir, rel, content, 'the wiki page'));
|
|
468
|
+
}
|
|
469
|
+
/** Called by `lane promote` and `lane rollback` before the lane file is replaced: the only way a lane edit reaches the cloud. */
|
|
470
|
+
export function writeCloudLane(projectDir, laneId, content) {
|
|
471
|
+
if (!existsSync(join(projectDir, CLOUD_FILE)))
|
|
472
|
+
return;
|
|
473
|
+
return locked(projectDir, () => writeDoc(projectDir, `lanes/${laneId}.yaml`, content, `lane ${laneId}`));
|
|
474
|
+
}
|
|
475
|
+
function required(projectDir) {
|
|
476
|
+
const config = loadCloud(projectDir);
|
|
477
|
+
if (!config)
|
|
478
|
+
throw new CloudError('not connected; run `codeloop cloud connect --url <mcp url> --key <api key>`');
|
|
479
|
+
return config;
|
|
480
|
+
}
|
|
481
|
+
/**
|
|
482
|
+
* Run before a command: pending writes are pushed, files nobody edited here are updated from the
|
|
483
|
+
* cloud, and wiki pages and config edited here are pushed. Returns what it did, one line each.
|
|
484
|
+
* With the cloud unreachable the command still runs on the local files.
|
|
485
|
+
*/
|
|
486
|
+
export function syncBefore(projectDir) {
|
|
487
|
+
if (!existsSync(join(projectDir, CLOUD_FILE)))
|
|
488
|
+
return [];
|
|
489
|
+
return withBoard(projectDir, () => {
|
|
490
|
+
const config = required(projectDir);
|
|
491
|
+
const sync = loadSync(projectDir);
|
|
492
|
+
let s;
|
|
493
|
+
try {
|
|
494
|
+
s = open(projectDir, config, sync, SYNC_TIMEOUT_MS);
|
|
495
|
+
}
|
|
496
|
+
catch (e) {
|
|
497
|
+
if (!unreachable(e))
|
|
498
|
+
throw e;
|
|
499
|
+
const pending = Object.values(sync.documents).filter(d => d.pending).length;
|
|
500
|
+
return [`warning: ${e.message}; working from the local files${pending ? ` (${pending} pending ${pending === 1 ? 'write' : 'writes'})` : ''}`];
|
|
501
|
+
}
|
|
502
|
+
try {
|
|
503
|
+
pushPending(s);
|
|
504
|
+
pullRows(s, 'unchanged');
|
|
505
|
+
pushRows(s, 'edits');
|
|
506
|
+
}
|
|
507
|
+
finally {
|
|
508
|
+
saveSync(projectDir, s.sync);
|
|
509
|
+
}
|
|
510
|
+
return s.notes;
|
|
511
|
+
});
|
|
512
|
+
}
|
|
513
|
+
export function push(projectDir, opts = {}) {
|
|
514
|
+
return locked(projectDir, () => {
|
|
515
|
+
const s = open(projectDir, required(projectDir), loadSync(projectDir));
|
|
516
|
+
try {
|
|
517
|
+
pushPending(s);
|
|
518
|
+
const { pushed, held } = pushRows(s, opts.force ? 'force' : 'all');
|
|
519
|
+
return { revision: s.sync.documents[BOARD].revision, wikiPages: pushed.filter(r => r.kind === 'wiki').length, held };
|
|
520
|
+
}
|
|
521
|
+
finally {
|
|
522
|
+
saveSync(projectDir, s.sync);
|
|
523
|
+
}
|
|
524
|
+
});
|
|
525
|
+
}
|
|
526
|
+
export function pull(projectDir, opts = {}) {
|
|
527
|
+
return withBoard(projectDir, () => {
|
|
528
|
+
const s = open(projectDir, required(projectDir), loadSync(projectDir));
|
|
529
|
+
try {
|
|
530
|
+
const stale = new Set(s.rows.filter(r => r.kind === 'wiki' && r.state !== 'in-sync').map(r => r.path));
|
|
531
|
+
pullRows(s, opts.force ? 'force' : 'board');
|
|
532
|
+
const wikiPages = s.rows.filter(r => stale.has(r.path) && r.state === 'in-sync').length;
|
|
533
|
+
return { revision: s.sync.documents[BOARD].revision, wikiPages, notes: s.notes.filter(n => !n.startsWith('pulled ')) };
|
|
534
|
+
}
|
|
535
|
+
finally {
|
|
536
|
+
saveSync(projectDir, s.sync);
|
|
537
|
+
}
|
|
538
|
+
});
|
|
539
|
+
}
|
|
540
|
+
export function status(projectDir) {
|
|
541
|
+
const config = required(projectDir);
|
|
542
|
+
const s = open(projectDir, config, loadSync(projectDir));
|
|
543
|
+
const board = s.rows.find(r => r.kind === 'board');
|
|
544
|
+
const local = JSON.parse(board.local ?? EMPTY_BOARD);
|
|
545
|
+
return {
|
|
546
|
+
url: config.url,
|
|
547
|
+
workspaceName: config.workspaceName,
|
|
548
|
+
boardTitle: config.boardTitle,
|
|
549
|
+
pageRevision: board.remote?.revision ?? 0,
|
|
550
|
+
lastSeenRevision: board.entry?.revision ?? 0,
|
|
551
|
+
localVersion: local.version,
|
|
552
|
+
cards: local.cards.length,
|
|
553
|
+
inSync: board.state === 'in-sync',
|
|
554
|
+
wikiPages: s.rows.filter(r => r.kind === 'wiki').length,
|
|
555
|
+
documents: s.rows.map(r => ({ path: r.path, kind: r.kind, state: r.state, ...(r.entry?.pending ? { pending: true } : {}) })),
|
|
556
|
+
};
|
|
557
|
+
}
|
|
558
|
+
/** Pushes what is pending, brings every document back into the repo files, then forgets the connection. */
|
|
559
|
+
export function disconnect(projectDir) {
|
|
560
|
+
return withBoard(projectDir, () => {
|
|
561
|
+
const s = open(projectDir, required(projectDir), loadSync(projectDir));
|
|
562
|
+
try {
|
|
563
|
+
pushPending(s);
|
|
564
|
+
pullRows(s, 'board');
|
|
565
|
+
pushRows(s, 'edits');
|
|
566
|
+
}
|
|
567
|
+
catch (e) {
|
|
568
|
+
saveSync(projectDir, s.sync);
|
|
569
|
+
throw e;
|
|
570
|
+
}
|
|
571
|
+
rmSync(join(projectDir, CLOUD_FILE));
|
|
572
|
+
rmSync(join(projectDir, SYNC_FILE), { force: true });
|
|
573
|
+
return { revision: s.sync.documents[BOARD].revision, wikiPages: s.rows.filter(r => r.kind === 'wiki').length };
|
|
574
|
+
});
|
|
575
|
+
}
|
|
576
|
+
export function search(projectDir, query, limit = 5) {
|
|
577
|
+
const [data] = callTools(required(projectDir), [{ name: 'KNOWLEDGE_SEARCH', args: { query, limit } }]);
|
|
578
|
+
return (data.results ?? []).map((r) => ({ title: r.title, id: r.id }));
|
|
579
|
+
}
|
|
580
|
+
//# sourceMappingURL=cloud.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cloud.js","sourceRoot":"","sources":["../../src/lib/cloud.ts"],"names":[],"mappings":"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"}
|