dreamteamer 0.6.0 → 0.6.1

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dreamteamer",
3
- "version": "0.6.0",
3
+ "version": "0.6.1",
4
4
  "description": "A workspace compiler for coding agents — schema-validated records as plain files over git, compiled into every harness",
5
5
  "license": "Apache-2.0",
6
6
  "author": "Gilad Khen <giladkhen@gmail.com>",
package/src/cli.js CHANGED
@@ -12,6 +12,12 @@ import { deriveEvents } from './events.js';
12
12
  import { commitPending } from './commit.js';
13
13
  import { Store } from './store.js';
14
14
 
15
+ // git calls whose failure we CATCH must not print git's own error: execFileSync forwards the
16
+ // child's stderr to ours unless told otherwise, so a handled "not a git repository" still
17
+ // reached the user's terminal. stdout stays piped because we read it.
18
+ const QUIET = ['ignore', 'pipe', 'ignore'];
19
+
20
+
15
21
  const USAGE = `usage: dreamteamer <command> | dreamteamer <collection> <verb> …
16
22
 
17
23
  commands:
@@ -230,7 +236,7 @@ export function run(argv) {
230
236
  }
231
237
 
232
238
  function tryGit(cwd, args) {
233
- try { return execFileSync('git', args, { cwd }).toString().trim() || null; } catch { return null; }
239
+ try { return execFileSync('git', args, { cwd, stdio: QUIET }).toString().trim() || null; } catch { return null; }
234
240
  }
235
241
 
236
242
  function watchAndRecompile(ws) {
package/src/commit.js CHANGED
@@ -6,6 +6,12 @@ import fs from 'node:fs';
6
6
  import path from 'node:path';
7
7
  import { pathToRecord } from './events.js';
8
8
 
9
+ // git calls whose failure we CATCH must not print git's own error: execFileSync forwards the
10
+ // child's stderr to ours unless told otherwise, so a handled "not a git repository" still
11
+ // reached the user's terminal. stdout stays piped because we read it.
12
+ const QUIET = ['ignore', 'pipe', 'ignore'];
13
+
14
+
9
15
  const VERB = { A: 'add', M: 'set', D: 'rm', R: 'rename', '?': 'add' };
10
16
 
11
17
  /** Record directories to watch, grouped by owning repo. System-stored collections are excluded:
@@ -31,7 +37,7 @@ function scopeByRepo(descriptors, only) {
31
37
  * is NOT a refusal condition — committing dirty records is this verb's entire job. */
32
38
  function inProgress(cwd) {
33
39
  let gitDir;
34
- try { gitDir = execFileSync('git', ['rev-parse', '--absolute-git-dir'], { cwd }).toString().trim(); }
40
+ try { gitDir = execFileSync('git', ['rev-parse', '--absolute-git-dir'], { cwd, stdio: QUIET }).toString().trim(); }
35
41
  catch { return 'not a git repository'; }
36
42
  for (const [marker, label] of [['MERGE_HEAD', 'merge'], ['rebase-merge', 'rebase'], ['rebase-apply', 'rebase'], ['CHERRY_PICK_HEAD', 'cherry-pick'], ['REVERT_HEAD', 'revert']]) {
37
43
  if (fs.existsSync(path.join(gitDir, marker))) return `a ${label} is in progress`;
@@ -42,7 +48,7 @@ function inProgress(cwd) {
42
48
  /** A commit on a detached HEAD is reachable only by sha. Worth saying out loud before making one;
43
49
  * not worth refusing over, since it is sometimes exactly what someone means to do. */
44
50
  function detached(cwd) {
45
- try { return execFileSync('git', ['symbolic-ref', '--quiet', 'HEAD'], { cwd }).toString().trim() === ''; }
51
+ try { return execFileSync('git', ['symbolic-ref', '--quiet', 'HEAD'], { cwd, stdio: QUIET }).toString().trim() === ''; }
46
52
  catch { return true; }
47
53
  }
48
54
 
@@ -57,7 +63,10 @@ function sample(root, repo, dirs, descriptors) {
57
63
  // `-uall` is load-bearing: by default porcelain COLLAPSES an untracked directory to a single
58
64
  // `?? data/notes/` entry, which maps to no record — so the first records of a brand-new
59
65
  // collection would be invisible and dt commit would report success having committed nothing.
60
- const out = execFileSync('git', ['status', '--porcelain', '-z', '-uall', '--', ...relDirs], { cwd }).toString();
66
+ // QUIET: the caller (cli `status`) catches a failure here so it can still print the rest of the
67
+ // report in a non-git folder — but git's own "fatal: not a git repository" was reaching the
68
+ // terminal anyway, which made a handled case look like a crash.
69
+ const out = execFileSync('git', ['status', '--porcelain', '-z', '-uall', '--', ...relDirs], { cwd, stdio: QUIET }).toString();
61
70
  const chunks = out.split('\0').filter((c) => c.length > 0);
62
71
  const rows = [];
63
72
  for (let i = 0; i < chunks.length; i++) {
package/src/init.js CHANGED
@@ -9,6 +9,12 @@ import { slugOrHash } from './template.js';
9
9
  import { discoverModules, KINDS } from './compile.js';
10
10
  import { Store } from './store.js';
11
11
 
12
+ // git calls whose failure we CATCH must not print git's own error: execFileSync forwards the
13
+ // child's stderr to ours unless told otherwise, so a handled "not a git repository" still
14
+ // reached the user's terminal. stdout stays piped because we read it.
15
+ const QUIET = ['ignore', 'pipe', 'ignore'];
16
+
17
+
12
18
  const SKELETON_KINDS = ['collections', 'skills', 'agents', 'commands', 'ui-views'];
13
19
 
14
20
  const GITIGNORE = `node_modules/
@@ -200,7 +206,7 @@ function buildClone(dest, name) {
200
206
  }
201
207
 
202
208
  function tryGit(cwd, args) {
203
- try { return execFileSync('git', args, { cwd }).toString().trim() || null; } catch { return null; }
209
+ try { return execFileSync('git', args, { cwd, stdio: QUIET }).toString().trim() || null; } catch { return null; }
204
210
  }
205
211
 
206
212
  function appendMissing(file, block) {
package/src/server.js CHANGED
@@ -16,6 +16,12 @@ import { commandsFor, recordResolver } from './record-commands.js';
16
16
  import { distinctValues } from './field-values.js';
17
17
  import { slugOrHash } from './template.js';
18
18
 
19
+ // git calls whose failure we CATCH must not print git's own error: execFileSync forwards the
20
+ // child's stderr to ours unless told otherwise, so a handled "not a git repository" still
21
+ // reached the user's terminal. stdout stays piped because we read it.
22
+ const QUIET = ['ignore', 'pipe', 'ignore'];
23
+
24
+
19
25
  export function startServer(ws, { port = 8080, host = '127.0.0.1' } = {}) {
20
26
  const app = express();
21
27
  app.use(express.json({ limit: '10mb' }));
@@ -42,7 +48,7 @@ export function startServer(ws, { port = 8080, host = '127.0.0.1' } = {}) {
42
48
  // so `@me` filters in ui-views resolve to the seeded user record.
43
49
  let operatorId = null;
44
50
  try {
45
- operatorId = slugOrHash(execFileSync('git', ['config', 'user.name'], { cwd: ws.root }).toString().trim());
51
+ operatorId = slugOrHash(execFileSync('git', ['config', 'user.name'], { cwd: ws.root, stdio: QUIET }).toString().trim());
46
52
  } catch { /* no git identity — @me filters simply won't narrow */ }
47
53
 
48
54
  api.get('/info', (req, res) => {
package/src/store.js CHANGED
@@ -12,6 +12,12 @@ import { generateId } from './template.js';
12
12
  import { parseRecord, parseRecordText, patternRe, fmtAjvError, unknownFields, walk, EXT, assertSafeId } from './records.js';
13
13
  import { normalizeRecord } from './temporal.js';
14
14
  import { NO_RUNTIME, loadDescriptors, runtimeDir, sourceRoots as compiledSourceRoots } from './runtime.js';
15
+
16
+ // git calls whose failure we CATCH must not print git's own error: execFileSync forwards the
17
+ // child's stderr to ours unless told otherwise, so a handled "not a git repository" still
18
+ // reached the user's terminal. stdout stays piped because we read it.
19
+ const QUIET = ['ignore', 'pipe', 'ignore'];
20
+
15
21
  export class Store {
16
22
  constructor({ root, pkg }) {
17
23
  this.root = root;
@@ -66,7 +72,7 @@ export class Store {
66
72
 
67
73
  // current HEAD — one cheap rev-parse per cache check vs a multi-thousand-file walk
68
74
  gitHead() {
69
- try { return execFileSync('git', ['rev-parse', 'HEAD'], { cwd: this.root }).toString().trim(); } catch { return 'no-git'; }
75
+ try { return execFileSync('git', ['rev-parse', 'HEAD'], { cwd: this.root, stdio: QUIET }).toString().trim(); } catch { return 'no-git'; }
70
76
  }
71
77
 
72
78
  ids(collection) {
@@ -128,7 +134,7 @@ export class Store {
128
134
  const relPath = path.relative(this.root, file);
129
135
  let previousContent;
130
136
  try {
131
- previousContent = execFileSync('git', ['show', `${hash}:${relPath}`], { cwd: this.root }).toString();
137
+ previousContent = execFileSync('git', ['show', `${hash}:${relPath}`], { cwd: this.root, stdio: QUIET }).toString();
132
138
  } catch {
133
139
  throw new Error(`${collection}/${id}: no content at ${hash} for ${relPath} — nothing was reverted.`);
134
140
  }